spring security四种实现方式 spring security四种实现方式
</div>
<div style="clear:both"></div><div style="border:solid 1px #ccc; background:#eee; float:left; min-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 >
<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 ></beans:bean>
<!-- 密码加密 -->
<beans:bean />
</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 >
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="mesecurityAccessDecisionManager"/>
<beans:property name="securityMetadataSource" ref="secureResourceFilterInvocationDefinitionSource" />
</beans:bean>
<!-- 获取访问url对应的所有权限 -->
<beans:bean />
<!-- 校验用户的权限是否足够 -->
<beans:bean />
- 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,需要实现的方法
[java] view plain copy
- /**
- * 返回用户所属权限
- */
- @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)方法
[java] view plain copy
- @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要
[java] view plain copy
- /**
- * 如果此处验证不通过,是不会执行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
[java] view plain copy
- 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的配置
[html] view plain copy
- <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 >
<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>
相关阅读:
Lintcode423-Valid Parentheses-Easy
Lintcode97-Maximum Depth of Binary Tree-Easy
Lintcode175-Revert Binary Tree-Easy
Lintcode469-Same Tree-Easy
Leetcode480-Binary Tree Paths-Easy
Lintcode481-Binary Tree Leaf Sum-Easy
Lintcode482-Binary Tree Level Sum-Easy
Lintcode376-Binary Tree Path Sum-Easy
SQL
Database
原文地址:https://www.cnblogs.com/jpfss/p/8529049.html
-
最新文章
-
V5.0.2 Xhorse VVDI Prog Adds BMW D160XX D80XX
Xhorse Key Tool Plus Program Porsche Cayenne S Key Solderless
VVDI Key Tool Plus program Range Rover 2017 Smart Key
How to use Xhorse VVDI Mini OBD to Read Peugeot Citroen PIN Code?
Solved! VVDIPROG V5.0.1 Unable to Start on Win10
Xhorse Dolphin XP005 Cut a B89 Key for Chevrolet Trailblazer
Xhorse VVDI MB V5.1.0 Adds deactivate voltage limit function
How to Adds BMW CAS3 Key by Xhorse VVDI Key Tool Max + Mini Prog?
How to Add A Key to 2009 Toyota Camry by Xhorse VVDI Mini OBD?
nodeJS---express4+passport实现用户注册登录验证
1.最简单配置spring-security.xml,实现1
2.实现UserDetailsService
3.实现动态过滤用户权限
4.实现AuthenticationProvider,自定义参数验证
Linux下C/C++帮助手册安装方法
GNU自动化工具使用全过程详解,以及在线手册