spring(20)
</div>
<div style="clear:both"></div><div style="border:solid 1px #ccc; background:#eee; float:left; min-width:200px;padding:4px 10px;"><p style="text-align:right;margin:0;"><span style="float:left;">目录<a href="http://blog.csdn.net/bao19901210/article/details/52574340" title="系统根据文章中H1到H6标签自动生成文章目录">(?)</a></span><a href="#" onclick="javascript:return openct(this);" title="展开">[+]</a></p><ol style="display:none;margin-left:14px;padding-left:14px;line-height:160%;"><li><a href="http://blog.csdn.net/bao19901210/article/details/52574340#t0">最简单配置spring-securityxml实现1</a></li><li><a href="http://blog.csdn.net/bao19901210/article/details/52574340#t1">实现UserDetailsService</a></li><li><a href="http://blog.csdn.net/bao19901210/article/details/52574340#t2">实现动态过滤用户权限</a></li><li><a href="http://blog.csdn.net/bao19901210/article/details/52574340#t3">实现AuthenticationProvider自定义参数验证</a></li></ol></div><div style="clear:both"></div><div id="article_content" class="article_content csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post" style="overflow: hidden;">
<link rel="stylesheet" href="http://csdnimg.cn/release/phoenix/production/htmledit_views-b569b0e3ef.css">
<div class="htmledit_views">
spring security实现方式大致可以分为这几种:
1.配置文件实现,只需要在配置文件中指定拦截的url所需要权限、配置userDetailsService指定用户名、密码、对应权限,就可以实现。
2.实现UserDetailsService,loadUserByUsername(String userName)方法,根据userName来实现自己的业务逻辑返回UserDetails的实现类,需要自定义User类实现UserDetails,比较重要的方法是getAuthorities(),用来返回该用户所拥有的权限。
3.通过自定义filter重写spring security拦截器,实现动态过滤用户权限。
4.通过自定义filter重写spring security拦截器,实现自定义参数来检验用户,并且过滤权限。
1.最简单配置spring-security.xml,实现1
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:security="http://www.springframework.org/schema/security"
- xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/security
- http://www.springframework.org/schema/security/spring-security-4.0.xsd">
- <!-- use-expressions:Spring 表达式语言配置访问控制 -->
- <security:http auto-config="true" use-expressions="false">
- <!-- 配置权限拦截,访问所有url,都需要用户登录,且拥有ROLE_USER权限 -->
- <security:intercept-url pattern="/**" access="ROLE_USER" />
- </security:http>
- <security:authentication-manager alias="authenticationManager">
- <security:authentication-provider>
- <!-- 配置默认用户,用户名:admin 密码:123456 拥有权限:ROLE_USER -->
- <security:user-service>
- <security:user name="admin" password="123456"
- authorities="ROLE_USER" />
- </security:user-service>
- </security:authentication-provider>
- </security:authentication-manager>
- </beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd"><!-- use-expressions:Spring 表达式语言配置访问控制 -->
<security:http auto-config="true" use-expressions="false">
<!-- 配置权限拦截,访问所有url,都需要用户登录,且拥有ROLE_USER权限 -->
<security:intercept-url pattern="/**" access="ROLE_USER" /> </security:http> <security:authentication-manager alias="authenticationManager">
<security:authentication-provider>
<!-- 配置默认用户,用户名:admin 密码:123456 拥有权限:ROLE_USER -->
<security:user-service>
<security:user name="admin" password="123456"
authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider> </security:authentication-manager></beans>
2.实现UserDetailsService
先整理下spring secruity验证流程:
springSecurity的登录验证是由org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter这个过滤器来完成的,在该类的父类AbstractAuthenticationProcessingFilter中有一个AuthenticationManager接口属性,验证工作主要是通过这个AuthenticationManager接口的实例来完成的。在默认情况下,springSecurity框架会把org.springframework.security.authentication.ProviderManager类的实例注入到该属性
UsernamePasswordAuthenticationFilter的验证过程如下:
1. 首先过滤器会调用自身的attemptAuthentication方法,从request中取出authentication, authentication是在org.springframework.security.web.context.SecurityContextPersistenceFilter过滤器中通过捕获用户提交的登录表单中的内容生成的一个org.springframework.security.core.Authentication接口实例.
2. 拿到authentication对象后,过滤器会调用ProviderManager类的authenticate方法,并传入该对象
3.ProviderManager类的authenticate方法中会调用类中的List<AuthenticationProvider> providers集合中的各个AuthenticationProvider接口实现类中的authenticate(Authentication authentication)方法进行验证,由此可见,真正的验证逻辑是由各个AuthenticationProvider接口实现类来完成的。DaoAuthenticationProvider类是默认情况下注入的一个AuthenticationProvider接口实现类
4.provider的实现类在验证用户时,会调用userDetailsService的实现类的loadUserByUsername方法来获取用户信息,
首先spring-security配置文件
- <?xml version="1.0" encoding="UTF-8"?>
- <beans:beans xmlns="http://www.springframework.org/schema/security"
- xmlns:beans="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
- http://www.springframework.org/schema/security
- http://www.springframework.org/schema/security/spring-security.xsd">
- <!-- use-expressions=”true” 需要使用表达式方式来写权限-->
- <http auto-config="true" use-expressions="false">
- <!--这是spring 提供的http/https信道安全的这个是重要的!你的请求信道是安全的!-->
- <!--
- 释放用户登陆page 允许任何人访问该页面 ,IS_AUTHENTICATED_ANONYMOUSLY表示不拦截
- 另一种不拦截资源的配置:<http pattern="/login.jsp" security="none">
- -->
- <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
- <!-- 配置用户正常访问page-->
- <intercept-url pattern="/**" access="ROLE_USER"/>
- <!-- 自定义用户登陆page default-target-url登陆成功跳转的page ,authentication-failure-url="/login.jsp?error=true"这里是登陆失败跳转的page-->
- <form-login login-page="/login.jsp" default-target-url="/jsp/index/main.jsp" authentication-failure-url="/login.jsp?error=true"/>
- <!-- 记住密码 -->
- <!-- <remember-me key="elim" user-service-ref="securityManager"/> -->
- </http>
- <authentication-manager alias="authenticationManager">
- <!--
- authentication-provider 引用UserDetailsService实现类时使用user-service-ref属性,引用authentication实现类时,使用ref属性
- 这两个属性的区别在于
- ref:直接将ref依赖的bean注入到AuthenticationProvider的providers集合中
- user-service-ref:定义DaoAuthenticationProvider的bean注入到AuthenticationProvider的providers集合中,
- 并且DaoAuthenticationProvider的变量userDetailsService由user-service-ref依赖的bean注入。
- -->
- <authentication-provider user-service-ref="msecurityManager">
- <!-- 密码加密 -->
- <password-encoder ref="myPasswordEncoder"/>
- </authentication-provider>
- </authentication-manager>
- <!-- 实现UserDetailsService -->
- <beans:bean id="msecurityManager" class="com.ultrapower.me.util.security.support.SecurityManagerSupport"></beans:bean>
- <!-- 密码加密 -->
- <beans:bean id="myPasswordEncoder" class="com.ultrapower.me.util.security.MyPasswordEncoder"/>
- </beans:beans>
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- use-expressions=”true” 需要使用表达式方式来写权限-->
<http auto-config="true" use-expressions="false">
<!--这是spring 提供的http/https信道安全的这个是重要的!你的请求信道是安全的!-->
<!--
释放用户登陆page 允许任何人访问该页面 ,IS_AUTHENTICATED_ANONYMOUSLY表示不拦截
另一种不拦截资源的配置:<http pattern="/login.jsp" security="none">
--><intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/> <!-- 配置用户正常访问page-->
<intercept-url pattern="/**" access="ROLE_USER"/> <!-- 自定义用户登陆page default-target-url登陆成功跳转的page ,authentication-failure-url="/login.jsp?error=true"这里是登陆失败跳转的page-->
<form-login login-page="/login.jsp" default-target-url="/jsp/index/main.jsp" authentication-failure-url="/login.jsp?error=true"/>
<!-- 记住密码 --><!-- <remember-me key="elim" user-service-ref="securityManager"/> -->
</http><authentication-manager alias="authenticationManager">
<!--
authentication-provider 引用UserDetailsService实现类时使用user-service-ref属性,引用authentication实现类时,使用ref属性
这两个属性的区别在于
ref:直接将ref依赖的bean注入到AuthenticationProvider的providers集合中
user-service-ref:定义DaoAuthenticationProvider的bean注入到AuthenticationProvider的providers集合中,
并且DaoAuthenticationProvider的变量userDetailsService由user-service-ref依赖的bean注入。
-->
<authentication-provider user-service-ref="msecurityManager">
<!-- 密码加密 -->
<password-encoder ref="myPasswordEncoder"/>
</authentication-provider>
</authentication-manager> <!-- 实现UserDetailsService -->
<beans:bean id="msecurityManager" class="com.ultrapower.me.util.security.support.SecurityManagerSupport"></beans:bean>
<!-- 密码加密 -->
<beans:bean id="myPasswordEncoder" class="com.ultrapower.me.util.security.MyPasswordEncoder"/></beans:beans>
userDetailsService实现:
- /**
- *
- */
- package com.ultrapower.me.util.security.support;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.springframework.dao.DataAccessException;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
- import com.ultrapower.me.util.Constants;
- import com.ultrapower.me.util.dbDao.SpringBeanUtil;
- import com.ultrapower.me.util.security.SecurityManager;
- import com.ultrapower.me.util.security.entity.Resource;
- import com.ultrapower.me.util.security.entity.Role;
- import com.ultrapower.me.util.security.entity.User;
- import com.ultrapower.me.util.task.PasswordUtils;
- public class SecurityManagerSupport implements UserDetailsService{
- private Log log = LogFactory.getLog(this.getClass().getName());
- public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
- // List<User> users = getHibernateTemplate().find("FROM User user WHERE user.name = ? AND user.disabled = false", userName);
- log.info("SecurityManagerSupport.loadUserByUsername.userName:"+userName);
- User user =null;
- if("admin".equals(userName)){
- Set<Role> roles = new HashSet<Role>() ;
- Role role = new Role();
- role.setRoleid("ROLE_USER");
- role.setRoleName("ROLE_USER");
- Set<Resource> resources=new HashSet<Resource>() ;
- Resource res = new Resource();
- res.setResid("ME001");
- res.setResName("首页");
- res.setResUrl("/jsp/index/main.jsp");
- res.setType("ROLE_USER");
- res.setRoles(roles);
- resources.add(res);
- role.setResources(resources);
- roles.add(role);
- user = new User();
- user.setAccount("admin");
- user.setDisabled(false);
- user.setPassword(PasswordUtils.entryptPassword(Constants.securityKey));
- log.info(user.getPassword());
- user.setRoles(roles);
- }
- return user;//返回UserDetails的实现user不为空,则验证通过
- }
- }
/**
*
*/
package com.ultrapower.me.util.security.support; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import com.ultrapower.me.util.Constants;
import com.ultrapower.me.util.dbDao.SpringBeanUtil;
import com.ultrapower.me.util.security.SecurityManager;
import com.ultrapower.me.util.security.entity.Resource;
import com.ultrapower.me.util.security.entity.Role;
import com.ultrapower.me.util.security.entity.User;
import com.ultrapower.me.util.task.PasswordUtils; public class SecurityManagerSupport implements UserDetailsService{
private Log log = LogFactory.getLog(this.getClass().getName());public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
// List<User> users = getHibernateTemplate().find("FROM User user WHERE user.name = ? AND user.disabled = false", userName);
log.info("SecurityManagerSupport.loadUserByUsername.userName:"+userName);User user =null;
if("admin".equals(userName)){
Set<Role> roles = new HashSet<Role>() ;
Role role = new Role();
role.setRoleid("ROLE_USER");
role.setRoleName("ROLE_USER"); Set<Resource> resources=new HashSet<Resource>() ; Resource res = new Resource();
res.setResid("ME001");
res.setResName("首页");
res.setResUrl("/jsp/index/main.jsp");
res.setType("ROLE_USER");
res.setRoles(roles);
resources.add(res); role.setResources(resources); roles.add(role);
user = new User();
user.setAccount("admin");
user.setDisabled(false);
user.setPassword(PasswordUtils.entryptPassword(Constants.securityKey));
log.info(user.getPassword());
user.setRoles(roles);
}
return user;//返回UserDetails的实现user不为空,则验证通过
}}
UserDetails实现:
- /**
- *
- */
- package com.ultrapower.me.util.security.entity;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.authority.SimpleGrantedAuthority;
- import org.springframework.security.core.userdetails.UserDetails;
- public class User implements UserDetails {
- private static final long serialVersionUID = 8026813053768023527L;
- private String account;
- private String name;
- private String password;
- private boolean disabled;
- private Set<Role> roles;
- private Map<String, List<Resource>> roleResources;
- /**
- * The default constructor
- */
- public User() {
- }
- /**
- * Returns the authorites string
- *
- * eg.
- * downpour --- ROLE_ADMIN,ROLE_USER
- * robbin --- ROLE_ADMIN
- *
- * @return
- */
- public String getAuthoritiesString() {
- List<String> authorities = new ArrayList<String>();
- for(GrantedAuthority authority : this.getAuthorities()) {
- authorities.add(authority.getAuthority());
- }
- return StringUtils.join(authorities, ",");
- }
- @Override
- public Collection<? extends GrantedAuthority> getAuthorities() {
- // 根据自定义逻辑来返回用户权限,如果用户权限返回空或者和拦截路径对应权限不同,验证不通过
- if(!roles.isEmpty()){
- List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
- GrantedAuthority au = new SimpleGrantedAuthority("ROLE_USER");
- list.add(au);
- return list;
- }
- return null;
- }
- /*
- * 密码
- */
- public String getPassword() {
- return password;
- }
- /*
- * 用户名
- */
- public String getUsername() {
- return name;
- }
- /*
- *帐号是否不过期,false则验证不通过
- */
- public boolean isAccountNonExpired() {
- return true;
- }
- /*
- * 帐号是否不锁定,false则验证不通过
- */
- public boolean isAccountNonLocked() {
- return true;
- }
- /*
- * 凭证是否不过期,false则验证不通过
- */
- public boolean isCredentialsNonExpired() {
- return true;
- }
- /*
- * 该帐号是否启用,false则验证不通过
- */
- public boolean isEnabled() {
- return !disabled;
- }
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
- /**
- * @return the disabled
- */
- public boolean isDisabled() {
- return disabled;
- }
- /**
- * @return the roles
- */
- public Set<Role> getRoles() {
- return roles;
- }
- /**
- * @return the roleResources
- */
- public Map<String, List<Resource>> getRoleResources() {
- // init roleResources for the first time
- System.out.println("---------------------------------------------------");
- if(this.roleResources == null) {
- this.roleResources = new HashMap<String, List<Resource>>();
- for(Role role : this.roles) {
- String roleName = role.getRoleName();
- Set<Resource> resources = role.getResources();
- for(Resource resource : resources) {
- String key = roleName + "_" + resource.getType();
- if(!this.roleResources.containsKey(key)) {
- this.roleResources.put(key, new ArrayList<Resource>());
- }
- this.roleResources.get(key).add(resource);
- }
- }
- }
- return this.roleResources;
- }
- /**
- * @param name the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
- /**
- * @param password the password to set
- */
- public void setPassword(String password) {
- this.password = password;
- }
- /**
- * @param disabled the disabled to set
- */
- public void setDisabled(boolean disabled) {
- this.disabled = disabled;
- }
- /**
- * @param roles the roles to set
- */
- public void setRoles(Set<Role> roles) {
- this.roles = roles;
- }
- public String getAccount() {
- return account;
- }
- public void setAccount(String account) {
- this.account = account;
- }
- public void setRoleResources(Map<String, List<Resource>> roleResources) {
- this.roleResources = roleResources;
- }
- }
/**
*
*/
package com.ultrapower.me.util.security.entity; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; public class User implements UserDetails {private static final long serialVersionUID = 8026813053768023527L; private String account; private String name; private String password; private boolean disabled; private Set<Role> roles; private Map<String, List<Resource>> roleResources; /**
* The default constructor
*/
public User() { } /**
* Returns the authorites string
*
* eg.
* downpour --- ROLE_ADMIN,ROLE_USER
* robbin --- ROLE_ADMIN
*
* @return
*/
public String getAuthoritiesString() {
List<String> authorities = new ArrayList<String>();
for(GrantedAuthority authority : this.getAuthorities()) {
authorities.add(authority.getAuthority());
}
return StringUtils.join(authorities, ",");
} @Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// 根据自定义逻辑来返回用户权限,如果用户权限返回空或者和拦截路径对应权限不同,验证不通过
if(!roles.isEmpty()){
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
GrantedAuthority au = new SimpleGrantedAuthority("ROLE_USER");
list.add(au);
return list;
}
return null;
} /*
* 密码
*/
public String getPassword() {
return password;
} /*
* 用户名
*/
public String getUsername() {
return name;
} /*
*帐号是否不过期,false则验证不通过
*/
public boolean isAccountNonExpired() {
return true;
} /*
* 帐号是否不锁定,false则验证不通过
*/
public boolean isAccountNonLocked() {
return true;
} /*
* 凭证是否不过期,false则验证不通过
*/
public boolean isCredentialsNonExpired() {
return true;
} /*
* 该帐号是否启用,false则验证不通过
*/
public boolean isEnabled() {
return !disabled;
} /**
* @return the name
*/
public String getName() {
return name;
} /**
* @return the disabled
*/
public boolean isDisabled() {
return disabled;
} /**
* @return the roles
*/
public Set<Role> getRoles() {
return roles;
} /**
* @return the roleResources
*/
public Map<String, List<Resource>> getRoleResources() {
// init roleResources for the first time
System.out.println("---------------------------------------------------");
if(this.roleResources == null) { this.roleResources = new HashMap<String, List<Resource>>(); for(Role role : this.roles) {
String roleName = role.getRoleName();
Set<Resource> resources = role.getResources();
for(Resource resource : resources) {
String key = roleName + "_" + resource.getType();
if(!this.roleResources.containsKey(key)) {
this.roleResources.put(key, new ArrayList<Resource>());
}
this.roleResources.get(key).add(resource);
}
} }
return this.roleResources;
} /**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
} /**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
} /**
* @param disabled the disabled to set
*/
public void setDisabled(boolean disabled) {
this.disabled = disabled;
} /**
* @param roles the roles to set
*/
public void setRoles(Set<Role> roles) {
this.roles = roles;
} public String getAccount() {
return account;
} public void setAccount(String account) {
this.account = account;
} public void setRoleResources(Map<String, List<Resource>> roleResources) {
this.roleResources = roleResources;
}}
3.实现动态过滤用户权限
- <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="securityInterceptor"/>
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="securityInterceptor"/>
在spring-security配置文件中添加如下配置
- <!-- 自定义拦截器 -->
- <beans:bean id="securityInterceptor" class="com.ultrapower.me.util.security.interceptor.SecurityInterceptor">
- <beans:property name="authenticationManager" ref="authenticationManager"/>
- <beans:property name="accessDecisionManager" ref="mesecurityAccessDecisionManager"/>
- <beans:property name="securityMetadataSource" ref="secureResourceFilterInvocationDefinitionSource" />
- </beans:bean>
- <!-- 获取访问url对应的所有权限 -->
- <beans:bean id="secureResourceFilterInvocationDefinitionSource" class="com.ultrapower.me.util.security.interceptor.SecureResourceFilterInvocationDefinitionSource" />
- <!-- 校验用户的权限是否足够 -->
- <beans:bean id="mesecurityAccessDecisionManager" class="com.ultrapower.me.util.security.interceptor.SecurityAccessDecisionManager" />
<!-- 自定义拦截器 -->
<beans:bean id="securityInterceptor" class="com.ultrapower.me.util.security.interceptor.SecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="mesecurityAccessDecisionManager"/>
<beans:property name="securityMetadataSource" ref="secureResourceFilterInvocationDefinitionSource" />
</beans:bean>
<!-- 获取访问url对应的所有权限 -->
<beans:bean id="secureResourceFilterInvocationDefinitionSource" class="com.ultrapower.me.util.security.interceptor.SecureResourceFilterInvocationDefinitionSource" />
<!-- 校验用户的权限是否足够 -->
<beans:bean id="mesecurityAccessDecisionManager" class="com.ultrapower.me.util.security.interceptor.SecurityAccessDecisionManager" />
- package com.ultrapower.me.util.security.interceptor;
- import java.io.IOException;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import org.springframework.security.access.SecurityMetadataSource;
- import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
- import org.springframework.security.access.intercept.InterceptorStatusToken;
- import org.springframework.security.web.FilterInvocation;
- import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
- public class SecurityInterceptor extends AbstractSecurityInterceptor implements Filter{
- //配置文件注入
- private FilterInvocationSecurityMetadataSource securityMetadataSource;
- public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
- return securityMetadataSource;
- }
- public void setSecurityMetadataSource(
- FilterInvocationSecurityMetadataSource securityMetadataSource) {
- this.securityMetadataSource = securityMetadataSource;
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- // TODO Auto-generated method stub\
- FilterInvocation fi = new FilterInvocation(request, response, chain);
- //fi里面有一个被拦截的url
- //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
- //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
- InterceptorStatusToken token = super.beforeInvocation(fi);
- try {
- //执行下一个拦截器
- fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
- } finally {
- super.afterInvocation(token, null);
- }
- }
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- // TODO Auto-generated method stub
- }
- @Override
- public Class<?> getSecureObjectClass() {
- // TODO Auto-generated method stub
- return FilterInvocation.class;
- }
- @Override
- public SecurityMetadataSource obtainSecurityMetadataSource() {
- // TODO Auto-generated method stub
- return this.securityMetadataSource;
- }
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- }
package com.ultrapower.me.util.security.interceptor; import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; public class SecurityInterceptor extends AbstractSecurityInterceptor implements Filter{//配置文件注入
private FilterInvocationSecurityMetadataSource securityMetadataSource; public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
return securityMetadataSource;
} public void setSecurityMetadataSource(
FilterInvocationSecurityMetadataSource securityMetadataSource) {
this.securityMetadataSource = securityMetadataSource;
} @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub\ FilterInvocation fi = new FilterInvocation(request, response, chain);
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
} } @Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub } @Override
public Class<?> getSecureObjectClass() {
// TODO Auto-generated method stub
return FilterInvocation.class;
} @Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
// TODO Auto-generated method stub
return this.securityMetadataSource;
} @Override
public void destroy() {
// TODO Auto-generated method stub
}}
登陆后,每次访问资源都会被这个拦截器拦截,会执行doFilter这个方法,这个方法调用了invoke方法,其中fi断点显示是一个url(可能重写了toString方法吧,但是里面还有一些方法的),最重要的是beforeInvocation这个方法,它首先会调用MyInvocationSecurityMetadataSource类的getAttributes方法获取被拦截url所需的权限,在调用MyAccessDecisionManager类decide方法判断用户是否够权限。弄完这一切就会执行下一个拦截器。
- /**
- *
- */
- package com.ultrapower.me.util.security.interceptor;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import javax.servlet.ServletContext;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.security.access.ConfigAttribute;
- import org.springframework.security.access.SecurityConfig;
- import org.springframework.security.web.FilterInvocation;
- import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
- import org.springframework.util.AntPathMatcher;
- import org.springframework.util.PathMatcher;
- public class SecureResourceFilterInvocationDefinitionSource implements FilterInvocationSecurityMetadataSource, InitializingBean {
- private PathMatcher matcher;
- private static Map<String, Collection<ConfigAttribute>> map = new HashMap<String, Collection<ConfigAttribute>>();
- /*
- * 初始化用户权限,为了简便操作没有从数据库获取
- * 实际操作可以从数据库中获取所有资源路径url所对应的权限
- */
- public void afterPropertiesSet() throws Exception {
- this.matcher = new AntPathMatcher();//用来匹配访问资源路径
- Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
- ConfigAttribute ca = new SecurityConfig("ROLE_USER");
- atts.add(ca);
- map.put("/jsp/index/main.jsp", atts);
- Collection<ConfigAttribute> attsno =new ArrayList<ConfigAttribute>();
- ConfigAttribute cano = new SecurityConfig("ROLE_NO");
- attsno.add(cano);
- map.put("/http://blog.csdn.net/u012367513/article/details/other.jsp", attsno);
- }
- @Override
- public Collection<ConfigAttribute> getAttributes(Object object)
- throws IllegalArgumentException {
- // TODO Auto-generated method stub
- FilterInvocation filterInvocation = (FilterInvocation) object;
- String requestURI = filterInvocation.getRequestUrl();
- //循环资源路径,当访问的Url和资源路径url匹配时,返回该Url所需要的权限
- for(Iterator<Map.Entry<String, Collection<ConfigAttribute>>> iter = map.entrySet().iterator(); iter.hasNext();) {
- Map.Entry<String, Collection<ConfigAttribute>> entry = iter.next();
- String url = entry.getKey();
- if(matcher.match(url, requestURI)) {
- return map.get(requestURI);
- }
- }
- return null;
- }
- @Override
- public Collection<ConfigAttribute> getAllConfigAttributes() {
- // TODO Auto-generated method stub
- return null;
- }
- /* (non-Javadoc)
- * @see org.springframework.security.intercept.ObjectDefinitionSource#getConfigAttributeDefinitions()
- */
- @SuppressWarnings("rawtypes")
- public Collection getConfigAttributeDefinitions() {
- return null;
- }
- /* (non-Javadoc)
- * @see org.springframework.security.intercept.ObjectDefinitionSource#supports(java.lang.Class)
- */
- public boolean supports(@SuppressWarnings("rawtypes") Class clazz) {
- return true;
- }
- /**
- *
- * @param filterInvocation
- * @return
- */
- @SuppressWarnings("unchecked")
- private Map<String, String> getUrlAuthorities(org.springframework.security.web.FilterInvocation filterInvocation) {
- ServletContext servletContext = filterInvocation.getHttpRequest().getSession().getServletContext();
- return (Map<String, String>)servletContext.getAttribute("urlAuthorities");
- }
- }
/**
*
*/
package com.ultrapower.me.util.security.interceptor; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import javax.servlet.ServletContext; import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher; public class SecureResourceFilterInvocationDefinitionSource implements FilterInvocationSecurityMetadataSource, InitializingBean {private PathMatcher matcher; private static Map<String, Collection<ConfigAttribute>> map = new HashMap<String, Collection<ConfigAttribute>>(); /*
* 初始化用户权限,为了简便操作没有从数据库获取
* 实际操作可以从数据库中获取所有资源路径url所对应的权限
*/
public void afterPropertiesSet() throws Exception {
this.matcher = new AntPathMatcher();//用来匹配访问资源路径
Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
ConfigAttribute ca = new SecurityConfig("ROLE_USER");
atts.add(ca);
map.put("/jsp/index/main.jsp", atts);
Collection<ConfigAttribute> attsno =new ArrayList<ConfigAttribute>();
ConfigAttribute cano = new SecurityConfig("ROLE_NO");
attsno.add(cano);
map.put("/http://blog.csdn.net/u012367513/article/details/other.jsp", attsno);
} @Override
public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
// TODO Auto-generated method stub
FilterInvocation filterInvocation = (FilterInvocation) object; String requestURI = filterInvocation.getRequestUrl();
//循环资源路径,当访问的Url和资源路径url匹配时,返回该Url所需要的权限
for(Iterator<Map.Entry<String, Collection<ConfigAttribute>>> iter = map.entrySet().iterator(); iter.hasNext();) {
Map.Entry<String, Collection<ConfigAttribute>> entry = iter.next();
String url = entry.getKey(); if(matcher.match(url, requestURI)) {
return map.get(requestURI);
}
} return null;
} @Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
// TODO Auto-generated method stub
return null;
} /* (non-Javadoc)
* @see org.springframework.security.intercept.ObjectDefinitionSource#getConfigAttributeDefinitions()
*/
@SuppressWarnings("rawtypes")
public Collection getConfigAttributeDefinitions() {
return null;
} /* (non-Javadoc)
* @see org.springframework.security.intercept.ObjectDefinitionSource#supports(java.lang.Class)
*/
public boolean supports(@SuppressWarnings("rawtypes") Class clazz) {
return true;
} /**
*
* @param filterInvocation
* @return
*/
@SuppressWarnings("unchecked")
private Map<String, String> getUrlAuthorities(org.springframework.security.web.FilterInvocation filterInvocation) {
ServletContext servletContext = filterInvocation.getHttpRequest().getSession().getServletContext();
return (Map<String, String>)servletContext.getAttribute("urlAuthorities");
}}
mesecurityAccessDecisionManager实现
- package com.ultrapower.me.util.security.interceptor;
- import java.util.Collection;
- import java.util.Iterator;
- import org.springframework.security.access.AccessDecisionManager;
- import org.springframework.security.access.AccessDeniedException;
- import org.springframework.security.access.ConfigAttribute;
- import org.springframework.security.access.SecurityConfig;
- import org.springframework.security.authentication.InsufficientAuthenticationException;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.GrantedAuthority;
- public class SecurityAccessDecisionManager implements AccessDecisionManager {
- /**
- * 检查用户是否够权限访问资源
- * authentication 是从spring的全局缓存SecurityContextHolder中拿到的,里面是用户的权限信息
- * object 是url
- * configAttributes 所需的权限
- * @see org.springframework.security.access.AccessDecisionManager#decide(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection)
- */
- @Override
- public void decide(Authentication authentication, Object object,
- Collection<ConfigAttribute> configAttributes)
- throws AccessDeniedException, InsufficientAuthenticationException {
- // 对应url没有权限时,直接跳出方法
- if(configAttributes == null){
- return;
- }
- Iterator<ConfigAttribute> ite=configAttributes.iterator();
- //判断用户所拥有的权限,是否符合对应的Url权限,如果实现了UserDetailsService,则用户权限是loadUserByUsername返回用户所对应的权限
- while(ite.hasNext()){
- ConfigAttribute ca=ite.next();
- String needRole=((SecurityConfig)ca).getAttribute();
- for(GrantedAuthority ga : authentication.getAuthorities()){
- System.out.println(":::::::::::::"+ga.getAuthority());
- if(needRole.equals(ga.getAuthority())){
- return;
- }
- }
- }
- //注意:执行这里,后台是会抛异常的,但是界面会跳转到所配的access-denied-page页面
- throw new AccessDeniedException("no right");
- }
- @Override
- public boolean supports(ConfigAttribute attribute) {
- return true;
- }
- @Override
- public boolean supports(Class<?> clazz) {
- return true;
- }
- }
package com.ultrapower.me.util.security.interceptor; import java.util.Collection;
import java.util.Iterator; import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; public class SecurityAccessDecisionManager implements AccessDecisionManager {/**
* 检查用户是否够权限访问资源
* authentication 是从spring的全局缓存SecurityContextHolder中拿到的,里面是用户的权限信息
* object 是url
* configAttributes 所需的权限
* @see org.springframework.security.access.AccessDecisionManager#decide(org.springframework.security.core.Authentication, java.lang.Object, java.util.Collection)
*/
@Override
public void decide(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
// 对应url没有权限时,直接跳出方法
if(configAttributes == null){
return;
} Iterator<ConfigAttribute> ite=configAttributes.iterator();
//判断用户所拥有的权限,是否符合对应的Url权限,如果实现了UserDetailsService,则用户权限是loadUserByUsername返回用户所对应的权限
while(ite.hasNext()){
ConfigAttribute ca=ite.next();
String needRole=((SecurityConfig)ca).getAttribute();
for(GrantedAuthority ga : authentication.getAuthorities()){
System.out.println(":::::::::::::"+ga.getAuthority());
if(needRole.equals(ga.getAuthority())){
return;
}
}
}
//注意:执行这里,后台是会抛异常的,但是界面会跳转到所配的access-denied-page页面
throw new AccessDeniedException("no right");
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}}
4.实现AuthenticationProvider,自定义参数验证
- /**
- * 凭证,用户密码
- */
- @Override
- public Object getCredentials() {
- return password;
- }
- /**
- * 当事人,登录名 用户Id
- */
- @Override
- public Object getPrincipal() {
- return userID;
- }
/**
* 凭证,用户密码
*/
@Override
public Object getCredentials() {
return password;
}/**
* 当事人,登录名 用户Id
*/
@Override
public Object getPrincipal() {
return userID;
}</pre><br><br></div>2.User类要实现Authentication,需要实现的方法
- /**
- * 返回用户所属权限
- */
- @Override
- public Collection<GrantedAuthority> getAuthorities() {
- return this.accesses;
- }
- @Override
- public Object getCredentials() {
- return null;
- }
- @Override
- public Object getDetails() {
- return null;
- }
- /**
- * 登录名称
- */
- @Override
- public Object getPrincipal() {
- return loginName;
- }
- /**
- * 是否认证
- */
- @Override
- public boolean isAuthenticated() {
- return this.authenticated;
- }
- /**
- * 设置是否认证字段
- */
- @Override
- public void setAuthenticated(boolean isAuthenticated)
- throws IllegalArgumentException {
- this.authenticated=isAuthenticated;
- }
/**
* 返回用户所属权限
*/
@Override
public Collection<GrantedAuthority> getAuthorities() {
return this.accesses;
}@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return null;
}
/**
* 登录名称
*/
@Override
public Object getPrincipal() {
return loginName;
}
/**
* 是否认证
*/
@Override
public boolean isAuthenticated() {
return this.authenticated;
}
/**
* 设置是否认证字段
*/
@Override
public void setAuthenticated(boolean isAuthenticated)
throws IllegalArgumentException {
this.authenticated=isAuthenticated;
}</pre><br><br></div>3.需要userService实现AuthenticationProvider的 authenticate(Authentication authentication)方法
- @SuppressWarnings("unchecked")
- @Override
- public Authentication authenticate(Authentication authentication)
- throws AuthenticationException {
- PassCardAuthenticationToken token=(PassCardAuthenticationToken)authentication;
- /*
- * 这里进行逻辑认证操作,可以获取token中的属性来自定义验证逻辑,代码验证逻辑可以不用管
- * 如果使用UserDetailsService的实现类来验证,就只能获取userName,不够灵活
- */
- if(token.getUserID()!=null&&token.getPassword()!=null){
- User user=(User)this.getDao().executeQueryUnique("User.loadByLoginName", QueryCmdType.QUERY_NAME, token.getUserID());
- String password=token.getPassword();
- if(this.passwordEncoder!=null){
- password=this.passwordEncoder.encodePassword(password, null);
- }
- if(!password.equalsIgnoreCase(user.getPassword())){
- token.setErrCode("2");
- return null;
- }
- if( token.isEnablePasscard() && usePassCard ){//token中激活密码卡且系统使用密码卡
- int position1=((token.getRow1()-1)*7)+token.getColumn1();
- int position2=((token.getRow2()-1)*7)+token.getColumn2();
- //System.out.println( "---pos:"+position1+"---"+position2 );
- if(user.getPassCardId()==null){
- token.setErrCode("10");
- return null;
- }
- PassCard passcard=this.passCardDao.findById(user.getPassCardId(), false);
- if(passcard==null||passcard.getStatus()==PassCardHelper.STATUS_CANCEL ){
- token.setErrCode("10");
- return null;
- }
- if(passcard.getConfusedContent()==null || passcard.getConfusedContent().length()<7*7*32 ){
- token.setErrCode("10");
- return null;
- }
- String content=passcard.getConfusedContent();
- int perLen=content.length()/49;
- String str1=content.substring((position1-1)*perLen, position1*perLen);
- String str2=content.substring((position2-1)*perLen, position2*perLen);
- String inputStr1=token.getCard1();
- String inputStr2=token.getCard2();
- if(this.passwordEncoder!=null){
- inputStr1 = md5.getMD5ofStr(md5.getMD5ofStr(inputStr1));
- inputStr2 = md5.getMD5ofStr(md5.getMD5ofStr(inputStr2));
- }
- if((!str1.equalsIgnoreCase(inputStr1))||(!str2.equalsIgnoreCase(inputStr2))){
- token.setErrCode("10");
- return null;
- }
- }
- user.setLastIp(token.getIp());
- user.setLastLogin(new Date());
- this.getDao().saveOrUpdate(user);
- user.setAuthenticated(true);
- /*
- * 导入一次角色权限,并且把权限set到User中,用于spring验证用户权限(getAuthorities方法)
- */
- List<UserRole> userRoles=(List<UserRole>)this.getDao().executeQueryList("UserRole.listRoleByUserID", QueryCmdType.QUERY_NAME, -1, -1, user.getId());
- Set<GrantedAuthority> accesses=new HashSet<GrantedAuthority>();
- for(UserRole ur:userRoles){
- accesses.add(ur.getRole());
- }
- user.getOrg().getOrgName();
- if(user.getOrg().getCertTypes()!=null) user.getOrg().getCertTypes().size();//延迟载入一下
- user.setAccesses(accesses);
- return user;
- }
- return null;
- }
@SuppressWarnings("unchecked")
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
PassCardAuthenticationToken token=(PassCardAuthenticationToken)authentication;
/*
* 这里进行逻辑认证操作,可以获取token中的属性来自定义验证逻辑,代码验证逻辑可以不用管
* 如果使用UserDetailsService的实现类来验证,就只能获取userName,不够灵活
*/
if(token.getUserID()!=null&&token.getPassword()!=null){
User user=(User)this.getDao().executeQueryUnique("User.loadByLoginName", QueryCmdType.QUERY_NAME, token.getUserID());String password=token.getPassword();
if(this.passwordEncoder!=null){
password=this.passwordEncoder.encodePassword(password, null);
} if(!password.equalsIgnoreCase(user.getPassword())){ token.setErrCode("2");
return null;
} if( token.isEnablePasscard() && usePassCard ){//token中激活密码卡且系统使用密码卡 int position1=((token.getRow1()-1)*7)+token.getColumn1();
int position2=((token.getRow2()-1)*7)+token.getColumn2();
//System.out.println( "---pos:"+position1+"---"+position2 ); if(user.getPassCardId()==null){
token.setErrCode("10");
return null;
}
PassCard passcard=this.passCardDao.findById(user.getPassCardId(), false); if(passcard==null||passcard.getStatus()==PassCardHelper.STATUS_CANCEL ){
token.setErrCode("10");
return null;
}
if(passcard.getConfusedContent()==null || passcard.getConfusedContent().length()<7*7*32 ){
token.setErrCode("10");
return null;
} String content=passcard.getConfusedContent();
int perLen=content.length()/49;
String str1=content.substring((position1-1)*perLen, position1*perLen);
String str2=content.substring((position2-1)*perLen, position2*perLen);
String inputStr1=token.getCard1();
String inputStr2=token.getCard2();
if(this.passwordEncoder!=null){
inputStr1 = md5.getMD5ofStr(md5.getMD5ofStr(inputStr1));
inputStr2 = md5.getMD5ofStr(md5.getMD5ofStr(inputStr2));
} if((!str1.equalsIgnoreCase(inputStr1))||(!str2.equalsIgnoreCase(inputStr2))){
token.setErrCode("10");
return null;
}
}
user.setLastIp(token.getIp());
user.setLastLogin(new Date());
this.getDao().saveOrUpdate(user);
user.setAuthenticated(true);
/*
* 导入一次角色权限,并且把权限set到User中,用于spring验证用户权限(getAuthorities方法)
*/
List<UserRole> userRoles=(List<UserRole>)this.getDao().executeQueryList("UserRole.listRoleByUserID", QueryCmdType.QUERY_NAME, -1, -1, user.getId());
Set<GrantedAuthority> accesses=new HashSet<GrantedAuthority>();
for(UserRole ur:userRoles){
accesses.add(ur.getRole());
}
user.getOrg().getOrgName();
if(user.getOrg().getCertTypes()!=null) user.getOrg().getCertTypes().size();//延迟载入一下
user.setAccesses(accesses);
return user;
}
return null;
}</pre><br></div>重写supports(Class<? extends Object> authentication)方法,authentication要
- /**
- * 如果此处验证不通过,是不会执行authentication方法的
- */
- @Override
- public boolean supports(Class<? extends Object> authentication) {
- return authentication.equals(PassCardAuthenticationToken.class);
- }
/**
* 如果此处验证不通过,是不会执行authentication方法的
*/
@Override
public boolean supports(Class<? extends Object> authentication) {
return authentication.equals(PassCardAuthenticationToken.class);
}4.定义filter,实现AbstractAuthenticationProcessingFilter的attemptAuthentication方法,用于获取在登录页面传递过来的参数,spring默认只获取userName(j_username),password(j_username),而且实现UserDetailsService时只传递username
- import java.io.IOException;
- import java.util.Date;
- import javax.servlet.ServletException;
- import javax.servlet.http.Cookie;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import org.apache.log4j.Logger;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.AuthenticationException;
- import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
- import org.springframework.util.StringUtils;
- import cn.edu.jszg.cert.user.UserLog;
- import cn.edu.jszg.cert.user.UserLogService;
- import cn.edu.jszg.cert.web.WebApplicationConfiguration;
- import cn.edu.jszg.cert.web.controller.portal.auth.RemoteDataValidator;
- import com.google.code.kaptcha.servlet.KaptchaServlet;
- public class PasscardAuthenticationProcessingFilter extends
- AbstractAuthenticationProcessingFilter {
- private String successPage = "/home/admin/index";
- private String failurePage = "/public/adminLoginEntry";
- private boolean forward = false;
- private boolean useVerifyCode=true;
- private String certLoginUrl;
- static Logger logger = Logger.getLogger(PasscardAuthenticationProcessingFilter.class);
- private WebApplicationConfiguration config;
- private UserLogService userLogService;
- public void setConfig(WebApplicationConfiguration config) {
- this.config = config;
- }
- /**
- * 实现AbstractAuthenticationProcessingFilter的有参构造
- * 没记错的话,相当于该filter的访问路径
- */
- protected PasscardAuthenticationProcessingFilter() {
- super("/adminLoginCheck");
- }
- public void setUseVerifyCode(boolean useVerifyCode) {
- this.useVerifyCode = useVerifyCode;
- }
- public void setUserLogService(UserLogService userLogService) {
- this.userLogService = userLogService;
- }
- public boolean validate(HttpServletRequest request) {
- String userId = request.getParameter("username");
- String md2 = request.getParameter("m");
- String l = request.getParameter("l");
- if (userId == null || md2 == null || l == null) {
- return false;
- }
- long longTime = Long.parseLong(l);
- if (longTime < new Date().getTime()) {
- return false;
- }
- try {
- String md1 = RemoteDataValidator.genExamMd5Digest(userId, longTime);
- if (md1.equals(md2))
- return true;
- } catch (Exception e) {
- //e.printStackTrace();
- }
- return false;
- }
- /**
- * 可以通过request获取页面传递过来的参数,并且set到相应的token中
- */
- @Override
- public Authentication attemptAuthentication(HttpServletRequest request,
- HttpServletResponse response) throws AuthenticationException,
- IOException, ServletException {
- // logger.warn("-----------------start证书登录用户----------");
- HttpSession s = request.getSession(true);
- PassCardAuthenticationToken token = new PassCardAuthenticationToken();
- String verifyCode = request.getParameter("verifyCode");
- String userID = request.getParameter("username");
- //....此处省略获取参数,并且验证、赋值的逻辑
- Authentication auth = null;
- try {
- //此处调用getAuthenticationManager的authenticate方法,当supports方法返回true时执行authenticate方法
- auth = this.getAuthenticationManager().authenticate(token);
- //此处为登录成功后,相应的处理逻辑
- if (auth == null || !auth.isAuthenticated()) {
- s.setAttribute("__login_error", token.getErrCode());
- } else {
- s.removeAttribute("__login_error");
- s.removeAttribute("__login_username");
- s.removeAttribute("__cert_userid");
- if( token.isEnablePasscard()) {
- s.removeAttribute("__passcard_row1");
- s.removeAttribute("__passcard_row2");
- s.removeAttribute("__passcard_column1");
- s.removeAttribute("__passcard_column2");
- }
- }
- } catch (AuthenticationException e) {
- s.setAttribute("__login_error", token.getErrCode());
- throw e;
- }
- return auth;
- }
- public void setSuccessPage(String successPage) {
- this.successPage = successPage;
- }
- public void setFailurePage(String failurePage) {
- this.failurePage = failurePage;
- }
- public void setForward(boolean forward) {
- this.forward = forward;
- }
- public void setCertLoginUrl(String certLoginUrl) {
- this.certLoginUrl = certLoginUrl;
- }
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- /*
- *该处理器实现了AuthenticationSuccessHandler, AuthenticationFailureHandler
- *用于处理登录成功或者失败后,跳转的界面
- */
- AuthenticationResultHandler handler = new AuthenticationResultHandler();
- handler.setForward(forward);
- handler.setLoginFailurePage(failurePage);
- handler.setLoginSuccessPage(successPage);
- handler.setCertLoginUrl(certLoginUrl);
- //设置父类中的处理器
- this.setAuthenticationSuccessHandler(handler);
- this.setAuthenticationFailureHandler(handler);
- }
- }
import java.io.IOException;
import java.util.Date; import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.apache.log4j.Logger;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.util.StringUtils; import cn.edu.jszg.cert.user.UserLog;
import cn.edu.jszg.cert.user.UserLogService;
import cn.edu.jszg.cert.web.WebApplicationConfiguration;
import cn.edu.jszg.cert.web.controller.portal.auth.RemoteDataValidator; import com.google.code.kaptcha.servlet.KaptchaServlet; public class PasscardAuthenticationProcessingFilter extends
AbstractAuthenticationProcessingFilter {
private String successPage = "/home/admin/index";
private String failurePage = "/public/adminLoginEntry";
private boolean forward = false;
private boolean useVerifyCode=true;
private String certLoginUrl;static Logger logger = Logger.getLogger(PasscardAuthenticationProcessingFilter.class); private WebApplicationConfiguration config;
private UserLogService userLogService; public void setConfig(WebApplicationConfiguration config) {
this.config = config;
} /**
* 实现AbstractAuthenticationProcessingFilter的有参构造
* 没记错的话,相当于该filter的访问路径
*/
protected PasscardAuthenticationProcessingFilter() {
super("/adminLoginCheck");
} public void setUseVerifyCode(boolean useVerifyCode) {
this.useVerifyCode = useVerifyCode;
} public void setUserLogService(UserLogService userLogService) {
this.userLogService = userLogService;
} public boolean validate(HttpServletRequest request) {
String userId = request.getParameter("username");
String md2 = request.getParameter("m");
String l = request.getParameter("l");
if (userId == null || md2 == null || l == null) {
return false;
}
long longTime = Long.parseLong(l);
if (longTime < new Date().getTime()) {
return false;
} try {
String md1 = RemoteDataValidator.genExamMd5Digest(userId, longTime);
if (md1.equals(md2))
return true; } catch (Exception e) {
//e.printStackTrace();
} return false;
} /**
* 可以通过request获取页面传递过来的参数,并且set到相应的token中
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException,
IOException, ServletException {// logger.warn("-----------------start证书登录用户----------");
HttpSession s = request.getSession(true);
PassCardAuthenticationToken token = new PassCardAuthenticationToken();String verifyCode = request.getParameter("verifyCode");
String userID = request.getParameter("username");
//....此处省略获取参数,并且验证、赋值的逻辑
Authentication auth = null; try {
//此处调用getAuthenticationManager的authenticate方法,当supports方法返回true时执行authenticate方法
auth = this.getAuthenticationManager().authenticate(token); //此处为登录成功后,相应的处理逻辑
if (auth == null || !auth.isAuthenticated()) {
s.setAttribute("__login_error", token.getErrCode());
} else {
s.removeAttribute("__login_error");
s.removeAttribute("__login_username");
s.removeAttribute("__cert_userid");
if( token.isEnablePasscard()) {
s.removeAttribute("__passcard_row1");
s.removeAttribute("__passcard_row2");
s.removeAttribute("__passcard_column1");
s.removeAttribute("__passcard_column2");
}
}
} catch (AuthenticationException e) {
s.setAttribute("__login_error", token.getErrCode());
throw e;
} return auth;
} public void setSuccessPage(String successPage) {
this.successPage = successPage;
} public void setFailurePage(String failurePage) {
this.failurePage = failurePage;
} public void setForward(boolean forward) {
this.forward = forward;
} public void setCertLoginUrl(String certLoginUrl) {
this.certLoginUrl = certLoginUrl;
} @Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
/*
*该处理器实现了AuthenticationSuccessHandler, AuthenticationFailureHandler
*用于处理登录成功或者失败后,跳转的界面
*/
AuthenticationResultHandler handler = new AuthenticationResultHandler();
handler.setForward(forward);
handler.setLoginFailurePage(failurePage);
handler.setLoginSuccessPage(successPage);
handler.setCertLoginUrl(certLoginUrl);
//设置父类中的处理器
this.setAuthenticationSuccessHandler(handler);
this.setAuthenticationFailureHandler(handler); }}
最后为spring-security配置文件中的配置,需要添加authentication-provider的引用,和filter的配置
- <security:authentication-manager alias="authenticationManager">
- <!-- 注意,这里仅仅是系统默认的认证机制,请在正式系统中明确知道其功能再使用 -->
- <security:authentication-provider ref="acocunt_defaultAnthentiactionProvider"/>
- <security:authentication-provider ref="registrationService"/>
- <security:authentication-provider ref="enrollmentService"/>
- <security:authentication-provider ref="userService"/>
- </security:authentication-manager>
- <bean id="passcard_filter" class="cn.edu.jszg.cert.security.PasscardAuthenticationProcessingFilter">
- <property name="authenticationManager" ref="authenticationManager"/>
- <property name="useVerifyCode" value="true"/>
- <property name="failurePage" value="/portal/home/auth/"></property>
- <property name="config" ref="webAppConfig"/>
- <property name="userLogService" ref="userLogService" />
- <property name="certLoginUrl" value="${cert.login.url}"/>
- </bean>
<security:authentication-manager alias="authenticationManager">
<!-- 注意,这里仅仅是系统默认的认证机制,请在正式系统中明确知道其功能再使用 -->
<security:authentication-provider ref="acocunt_defaultAnthentiactionProvider"/>
<security:authentication-provider ref="registrationService"/>
<security:authentication-provider ref="enrollmentService"/>
<security:authentication-provider ref="userService"/>
</security:authentication-manager>
<bean id="passcard_filter" class="cn.edu.jszg.cert.security.PasscardAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="useVerifyCode" value="true"/>
<property name="failurePage" value="/portal/home/auth/"></property>
<property name="config" ref="webAppConfig"/>
<property name="userLogService" ref="userLogService" />
<property name="certLoginUrl" value="${cert.login.url}"/>
</bean>还要在http中添加<security:custom-filter ref="passcard_filter" after="SECURITY_CONTEXT_FILTER"/>
-
</ul>
<div style="clear:both; height:10px;"></div>
</div>