`
zhuzhiguosnail
  • 浏览: 110925 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring Security

阅读更多

使用Spring Security 3 来实现多种用户类型的登录方式,在我看来,大致分为两大步,第一步是控制多种用户登录类型的登录界面的展示,第二步是控制多种用户登录的验证方式,而第二大步又可分为三个小步来展开,第一小步是验证过滤器,第二小步是验证凭证的制作,第三小步是验证用户凭证,在这里我将就这几步的分析与实现一步一步展开来进行描述。

 

      这里我假定有这样一个系统,分为前台用户和后台用户两种用户类型,针对这两种不同的用户,相应的验证是不一样的,前台用户登录需要提供邮箱地址和电话号码,而后台用户需要提供我们在登录方式中最为常见的用户名,密码和验证码,两种登录类型的登录界面和登录的验证处理流程都不相同,拥有自己的验证处理,验证成功的处理,验证失败的处理等。这里我会用四篇文章来详细阐述整个验证的流程实现,每一篇文章后都会附有我的项目压缩文件,有兴趣的朋友可以下载来进行尝试,我使用的是Maven来管理项目,项目的框架是Spring+Hibernate,使用到的开发工具是IntelliJ,这里我要给IntelliJ打个广告,当然是无偿的,呵呵,在这之前我曾使用过NetBeans,Eclipse等开发工具,IntelliJ是我使用过的最为优秀的开发工具,有兴趣的同学可以尝试下。

 

Spring Security 3多用户登录实现之二 多登录界面展示

接前讲,首先针对一个多种用户类型的登录需求,需要先实现多种用户类型的登录界面的展示,Spring Security提供了这样一个接口来帮助我们实现多种用户类型的登录界面的展示,这个接口就是AuthenticationEntryPoint, 实现这样一个接口,我们就可以随心所欲的控制登录界面的展示了,当我们访问一个受权限的资源,而当前又没有权限访问时,Spring Security就会将处理导向这个接口的实现。针对前讲我所提到的需求,在这里我将实现前台用户和后台用户登录界面的展示,先来看看我的源码实现吧,在这里为了实现多用户类型的登录,很多场景我都需要根据相应的请求参数或地址来判断我需要导向哪个URL地址,我在这里特实现了一个共用的接口和类,接口名为DirectUrlResolver。

 

 

 

Java代码  收藏代码
  1. package com.template.security.shared;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4.   
  5. /** 
  6.  * Created by IntelliJ IDEA. 
  7.  * User: Zhong Gang 
  8.  * Date: 12-11-9 
  9.  * Time: 下午7:11 
  10.  */  
  11. public interface DirectUrlResolver {  
  12.   
  13.     boolean support(HttpServletRequest request);  
  14.   
  15.     String directUrl();  
  16. }  

 

 

Java代码  收藏代码
  1. package com.template.security.shared;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4.   
  5. /** 
  6.  * Created by IntelliJ IDEA. 
  7.  * User: Zhong Gang 
  8.  * Date: 12-11-9 
  9.  * Time: 下午7:12 
  10.  */  
  11. public abstract class AbstractDirectUrlResolver implements DirectUrlResolver {  
  12.     protected String pattern;  
  13.     protected String directUrl;  
  14.   
  15.     @Override  
  16.     public abstract boolean support(HttpServletRequest request);  
  17.   
  18.     @Override  
  19.     public String directUrl() {  
  20.         return this.directUrl;  
  21.     }  
  22.   
  23.     public void setPattern(String pattern) {  
  24.         this.pattern = pattern;  
  25.     }  
  26.   
  27.     public void setDirectUrl(String directUrl) {  
  28.         this.directUrl = directUrl;  
  29.     }  
  30. }  

 

Java代码  收藏代码
  1. package com.template.security.shared;  
  2.   
  3. import com.template.utils.StringUtils;  
  4.   
  5. import javax.servlet.http.HttpServletRequest;  
  6.   
  7. /** 
  8.  * Created by IntelliJ IDEA. 
  9.  * User: Zhong Gang 
  10.  * Date: 12-11-9 
  11.  * Time: 下午7:13 
  12.  */  
  13. public class RequestParameterDirectUrlResolver extends AbstractDirectUrlResolver {  
  14.     private String parameterName;  
  15.   
  16.     @Override  
  17.     public boolean support(HttpServletRequest request) {  
  18.         String parameterValue = request.getParameter(parameterName);  
  19.         if (StringUtils.isEmpty(parameterValue)) {  
  20.             return false;  
  21.         }  
  22.         return parameterValue.equals(this.pattern);  
  23.     }  
  24.   
  25.     public void setParameterName(String parameterName) {  
  26.         this.parameterName = parameterName;  
  27.     }  
  28. }  

 

 

 

Java代码  收藏代码
  1. package com.template.security.shared;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4.   
  5. /** 
  6.  * Created by IntelliJ IDEA. 
  7.  * User: Zhong Gang 
  8.  * Date: 12-11-9 
  9.  * Time: 下午7:13 
  10.  */  
  11. public class RequestUriDirectUrlResolver extends AbstractDirectUrlResolver {  
  12.   
  13.     @Override  
  14.     public boolean support(HttpServletRequest request) {  
  15.         String requestURI = request.getRequestURI();  
  16.         return requestURI.contains(this.pattern);  
  17.     }  
  18. }  

 

     RequestParameterDirectUrlResolver和RequestUriDirectUrlResolver都实现了DirectUrlResolver这样一个接口,前者的实现是根据相应请求中的参数来判断, 而后者的实现是根据相应的请求地址来判断。

 

    现在让我们来看看如何通过实现AuthenticationEntryPoint接口来控制什么时候展示前台登录界面,什么时候展示后台登录界面的吧。

 

 

Java代码  收藏代码
  1. package com.template.security.login;  
  2.   
  3. import com.template.security.shared.DirectUrlResolver;  
  4. import org.springframework.security.core.AuthenticationException;  
  5. import org.springframework.security.web.AuthenticationEntryPoint;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import java.io.IOException;  
  11. import java.util.ArrayList;  
  12. import java.util.List;  
  13.   
  14. /** 
  15.  * Created by IntelliJ IDEA. 
  16.  * User: Zhong Gang 
  17.  * Date: 12-11-9 
  18.  * Time: 下午7:40 
  19.  */  
  20. public class MultipleAuthenticationLoginEntry implements AuthenticationEntryPoint {  
  21.     private String defaultLoginUrl;  
  22.     private List<DirectUrlResolver> directUrlResolvers = new ArrayList<DirectUrlResolver>();  
  23.   
  24.   
  25.     @Override  
  26.     public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {  
  27.         for (DirectUrlResolver directUrlResolver : directUrlResolvers) {  
  28.             if (directUrlResolver.support(request)) {  
  29.                 String loginUrl = directUrlResolver.directUrl();  
  30.                 response.sendRedirect(loginUrl);  
  31.                 return;  
  32.             }  
  33.         }  
  34.   
  35.         response.sendRedirect(defaultLoginUrl);  
  36.     }  
  37.   
  38.     public void setDefaultLoginUrl(String defaultLoginUrl) {  
  39.         this.defaultLoginUrl = defaultLoginUrl;  
  40.     }  
  41.   
  42.     public void setDirectUrlResolvers(List<DirectUrlResolver> directUrlResolvers) {  
  43.         this.directUrlResolvers = directUrlResolvers;  
  44.     }  
  45. }  

 

     再来看看在Spring配置文件中是如何对相应的登录入口进行配置的吧

 

 

Xml代码  收藏代码
  1. <beans:bean id="multipleAuthenticationLoginEntry"  
  2.                 class="com.template.security.login.MultipleAuthenticationLoginEntry">  
  3.         <beans:property name="defaultLoginUrl" value="/backend/login"/>  
  4.         <beans:property name="directUrlResolvers">  
  5.             <beans:list>  
  6.                 <beans:ref bean="backendLoginEntry"/>  
  7.                 <beans:ref bean="forendLoginEntry"/>  
  8.             </beans:list>  
  9.         </beans:property>  
  10.     </beans:bean>  
  11.   
  12.     <beans:bean id="backendLoginEntry" class="com.template.security.shared.RequestUriDirectUrlResolver">  
  13.         <beans:property name="pattern" value="/backend"/>  
  14.         <beans:property name="directUrl" value="/backend/login"/>  
  15.     </beans:bean>  
  16.   
  17.     <beans:bean id="forendLoginEntry" class="com.template.security.shared.RequestUriDirectUrlResolver">  
  18.         <beans:property name="pattern" value="/forend"/>  
  19.         <beans:property name="directUrl" value="/forend/login"/>  
  20.     </beans:bean>  

 

   这里我是根据请求的地址中是否包括backend或forend来判断用户是进行前台登录或后台登录的, 这可以从配置文件中的backendLoginEntry和forendLoginEntry中的pattern属性看出,这个pattern的作用就是判断用户是进行前台登录或后台登录的依据,而directUrl则是我们想要导向的登录界面地址。

Spring Security 3多用户登录实现之三 验证过滤器

当填写完成登录表单提交后,首先会被对应的提交表单提起的过滤器进行拦截,这里过滤器的作用就是拦截登录表单提交验证请求,并根据相应的表单信息构造对应的登录凭证,这里来看看过滤器是如何构造相应的用户凭证。

 

 

Java代码  收藏代码
  1. package com.template.security.filter;  
  2.   
  3. import org.springframework.security.core.Authentication;  
  4. import org.springframework.security.core.AuthenticationException;  
  5. import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import java.io.IOException;  
  11. import java.util.ArrayList;  
  12. import java.util.List;  
  13.   
  14. /** 
  15.  * Created by IntelliJ IDEA. 
  16.  * User: Zhong Gang 
  17.  * Date: 12-11-9 
  18.  * Time: 下午10:00 
  19.  */  
  20. public class MultipleAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {  
  21.     private List<AuthenticationTokenResolver> tokenResolvers = new ArrayList<AuthenticationTokenResolver>();  
  22.   
  23.     /** 
  24.      * @param defaultFilterProcessesUrl the default value for <tt>filterProcessesUrl</tt>. 
  25.      */  
  26.     protected MultipleAuthenticationProcessingFilter(String defaultFilterProcessesUrl) {  
  27.         super(defaultFilterProcessesUrl);  
  28.     }  
  29.   
  30.     @Override  
  31.     public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {  
  32.         for (AuthenticationTokenResolver tokenResolver : tokenResolvers) {  
  33.             if (tokenResolver.support(request)) {  
  34.                 Authentication authentication = tokenResolver.resolve(request);  
  35.                 return this.getAuthenticationManager().authenticate(authentication);  
  36.             }  
  37.         }  
  38.   
  39.         throw new UnsupportedOperationException("No authentication token resolver found!");  
  40.     }  
  41.   
  42.     public void setTokenResolvers(List<AuthenticationTokenResolver> tokenResolvers) {  
  43.         this.tokenResolvers = tokenResolvers;  
  44.     }  
  45. }  

 

 

Java代码  收藏代码
  1. package com.template.security.filter;  
  2.   
  3. import org.springframework.security.core.Authentication;  
  4.   
  5. import javax.servlet.http.HttpServletRequest;  
  6.   
  7. /** 
  8.  * Created by IntelliJ IDEA. 
  9.  * User: Zhong Gang 
  10.  * Date: 12-11-9 
  11.  * Time: 下午10:08 
  12.  */  
  13. public interface AuthenticationTokenResolver {  
  14.   
  15.     boolean support(HttpServletRequest request);  
  16.   
  17.   
  18.     Authentication resolve(HttpServletRequest request);  
  19.   
  20. }  

 

 

Java代码  收藏代码
  1. package com.template.security.filter;  
  2.   
  3. import com.template.utils.StringUtils;  
  4. import org.springframework.security.core.Authentication;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7.   
  8. /** 
  9.  * Created by IntelliJ IDEA. 
  10.  * User: Zhong Gang 
  11.  * Date: 12-11-9 
  12.  * Time: 下午10:27 
  13.  */  
  14. public abstract class AbstractAuthenticationTokenResolver implements AuthenticationTokenResolver {  
  15.     protected String parameterName;  
  16.     protected String parameterValue;  
  17.   
  18.     protected AbstractAuthenticationTokenResolver() {  
  19.     }  
  20.   
  21.     protected AbstractAuthenticationTokenResolver(String parameterName) {  
  22.         this.parameterName = parameterName;  
  23.     }  
  24.   
  25.     @Override  
  26.     public boolean support(HttpServletRequest request) {  
  27.         String parameterValue = request.getParameter(parameterName);  
  28.         if (StringUtils.isEmpty(parameterValue)) {  
  29.             return false;  
  30.         }  
  31.         return parameterValue.equals(this.parameterValue);  
  32.     }  
  33.   
  34.     @Override  
  35.     public abstract Authentication resolve(HttpServletRequest request);  
  36.   
  37.     public void setParameterName(String parameterName) {  
  38.         this.parameterName = parameterName;  
  39.     }  
  40.   
  41.     public void setParameterValue(String parameterValue) {  
  42.         this.parameterValue = parameterValue;  
  43.     }  
  44. }  

 

 

Java代码  收藏代码
  1. package com.template.security.filter;  
  2.   
  3. import com.template.security.authentication.token.BackendAuthenticationToken;  
  4. import org.springframework.security.core.Authentication;  
  5. import org.springframework.security.core.GrantedAuthority;  
  6. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  7.   
  8. import javax.servlet.http.HttpServletRequest;  
  9. import java.util.ArrayList;  
  10. import java.util.List;  
  11.   
  12. /** 
  13.  * Created by IntelliJ IDEA. 
  14.  * User: Zhong Gang 
  15.  * Date: 12-11-9 
  16.  * Time: 下午10:29 
  17.  */  
  18. public class BackendAuthenticationTokenResolver extends AbstractAuthenticationTokenResolver {  
  19.   
  20.     protected BackendAuthenticationTokenResolver() {  
  21.         super();  
  22.     }  
  23.   
  24.     @Override  
  25.     public Authentication resolve(HttpServletRequest request) {  
  26.         String username = request.getParameter("username");  
  27.         String password = request.getParameter("password");  
  28.         String captcha = request.getParameter("captcha");  
  29.         List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();  
  30.         authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));  
  31.         return new BackendAuthenticationToken(username, password, authorities, captcha);  
  32.     }  
  33. }  

 

 

Java代码  收藏代码
  1. package com.template.security.filter;  
  2.   
  3. import com.template.security.authentication.token.ForendAuthenticationToken;  
  4. import org.springframework.security.core.Authentication;  
  5. import org.springframework.security.core.GrantedAuthority;  
  6. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  7.   
  8. import javax.servlet.http.HttpServletRequest;  
  9. import java.util.ArrayList;  
  10. import java.util.List;  
  11.   
  12. /** 
  13.  * Created by IntelliJ IDEA. 
  14.  * User: Zhong Gang 
  15.  * Date: 12-11-9 
  16.  * Time: 下午10:29 
  17.  */  
  18. public class ForendAuthenticationTokenResolver extends AbstractAuthenticationTokenResolver {  
  19.   
  20.     protected ForendAuthenticationTokenResolver() {  
  21.         super();  
  22.     }  
  23.   
  24.     @Override  
  25.     public Authentication resolve(HttpServletRequest request) {  
  26.         String email = request.getParameter("email");  
  27.         String phone = request.getParameter("phone");  
  28.         List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();  
  29.         authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));  
  30.         return new ForendAuthenticationToken(email, phone, authorities);  
  31.     }  
  32.   
  33. }  

 

    这里实现AbstractAuthenticationProcessingFilter接口的类MultipleAuthenticationProcessingFilter,用来根据相应的登录表单提交信息构造相应的登录用户凭证。为了实现根据前台登录表单信息构造前台用户凭证,根据后台登录表单信息构造后台用户凭证,使用了策略模式来实现,实现AbstractAuthenticationTokenResolver接口的BackendAuthenticationTokenResolver和ForendAuthenticationTokenResolver分别用来构造后台用户凭证和前台用户凭证,再来看看配置文件是如何进行配置的吧。

 

 

Xml代码  收藏代码
  1. <beans:bean id="multipleAuthenticationProcessingFilter"  
  2.                 class="com.template.security.filter.MultipleAuthenticationProcessingFilter">  
  3.         <beans:constructor-arg value="/login/check"/>  
  4.         <beans:property name="tokenResolvers">  
  5.             <beans:list>  
  6.                 <beans:ref bean="backendAuthenticationTokenResolver"/>  
  7.                 <beans:ref bean="forendAuthenticationTokenResolver"/>  
  8.             </beans:list>  
  9.         </beans:property>  
  10.         <beans:property name="authenticationManager" ref="authenticationManager"/>  
  11.         <beans:property name="authenticationSuccessHandler" ref="multipleAuthenticationSuccessHandler"/>  
  12.         <beans:property name="authenticationFailureHandler" ref="multipleAuthenticationFailureHandler"/>  
  13.     </beans:bean>  
  14.   
  15.     <beans:bean id="backendAuthenticationTokenResolver"  
  16.                 class="com.template.security.filter.BackendAuthenticationTokenResolver">  
  17.         <beans:property name="parameterName" value="token"/>  
  18.         <beans:property name="parameterValue" value="backend"/>  
  19.     </beans:bean>  
  20.   
  21.     <beans:bean id="forendAuthenticationTokenResolver"  
  22.                 class="com.template.security.filter.ForendAuthenticationTokenResolver">  
  23.         <beans:property name="parameterName" value="token"/>  
  24.         <beans:property name="parameterValue" value="forend"/>  
  25.     </beans:bean>  

 

    这里不论是前台登录还是后台登录,都提交到相同的地址/login/check,不过为了区分请求到底是前台登录认证还是后台登录认证,这里使用了一个名为token的请求参数来区分,当token的值为backend的时候表明是后台登录认证,当token的值为forend的时候表明是前台登录认证。

 

   <custom-filter ref="multipleAuthenticationProcessingFilter" before="FORM_LOGIN_FILTER"/>

 

   这段配置表明自定义的认证过滤器将在Spring Security默认的UsernamePasswordAuthenticationFilter前执行,研究UsernamePasswordAuthenticationFilter源码你就会发现平时使用到的登录认证请求地址j_spring_security_check就是被这个过滤器进行拦截并进行处理的,所以如果只是简单的登录认证,你只需要在登录页面进行一些修改就完成可以了,因为后台的处理已经完全交由Spring Security来帮我们处理了。

Spring Security 3多用户登录实现之四 用户凭证

前讲讲到AuthenticationFilter会拦截我们的登录表单提交信息并根据相应的信息构造出对应的用户凭证,这里的用户凭证将会贯穿整个Spring Security安全验证过程,如果验证用户凭证成功,我们可以为相应的用户凭证分配相应的权限,并将用户导向登录成功的界面。来看看这里的多种类型用户登录凭证的实现吧,这里主要实现了两种用户凭证,一种是前台用户登录凭证,一种是后台用户登录凭证。

 

 

Java代码  收藏代码
  1. package com.template.security.authentication.token;  
  2.   
  3. import org.springframework.security.authentication.AbstractAuthenticationToken;  
  4. import org.springframework.security.core.GrantedAuthority;  
  5. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  6.   
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. /** 
  11.  * Created by IntelliJ IDEA. 
  12.  * User: Zhong Gang 
  13.  * Date: 12-11-4 
  14.  * Time: 下午11:23 
  15.  */  
  16. public class ForendAuthenticationToken extends AbstractAuthenticationToken {  
  17.     private String email;  
  18.     private String phone;  
  19.   
  20.     public ForendAuthenticationToken(String email, String phone, List<GrantedAuthority> grantedAuthorities) {  
  21.         super(grantedAuthorities);  
  22.         this.email = email;  
  23.         this.phone = phone;  
  24.     }  
  25.   
  26.     public String getEmail() {  
  27.         return email;  
  28.     }  
  29.   
  30.     public String getPhone() {  
  31.         return phone;  
  32.     }  
  33.   
  34.     @Override  
  35.     public Object getCredentials() {  
  36.         return null;  
  37.     }  
  38.   
  39.     @Override  
  40.     public Object getPrincipal() {  
  41.         return null;  
  42.     }  
  43. }  

 

 

Java代码  收藏代码
  1. package com.template.security.authentication.token;  
  2.   
  3. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
  4. import org.springframework.security.core.GrantedAuthority;  
  5.   
  6. import java.util.Collection;  
  7.   
  8. /** 
  9.  * Created by IntelliJ IDEA. 
  10.  * User: Zhong Gang 
  11.  * Date: 12-11-4 
  12.  * Time: 下午11:24 
  13.  */  
  14. public class BackendAuthenticationToken extends UsernamePasswordAuthenticationToken {  
  15.     private String captcha;  
  16.   
  17.     public BackendAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities, String captcha) {  
  18.         super(principal, credentials, authorities);  
  19.         this.captcha = captcha;  
  20.     }  
  21.   
  22.     public String getCaptcha() {  
  23.         return captcha;  
  24.     }  
  25. }  

 

    为了标志我们创建的类为一个用户凭证并且能够被Spring Security识别,我们需要实现Authentication接口,因为Spring Security为我们提供了一个抽象的凭证,所以这里我的前台凭证就继承了这样一个抽象的凭证类,名为AbstractAuthenticationToken, 根据前台表单的提交信息有邮件地址和电话号码,所以实现的ForendAuthenticationToken包含这样两个属性,而Spring Security为我们提供了常见的用户名和密码的登录凭证实现,我的后台登录表单信息只是多了一个验证码,所以我直接继承了UsernamePasswordAuthenticationToken这样一个类。

Spring Security 3多用户登录实现之五 验证用户凭证

 

有了用户凭证后, 如何验证用户的凭证是否正确呢, 这就需要借助AuthenticationManager了, AuthenticationManager可以包含多个AuthenticationProvider, 每个AuthenticationProvider都会针对特定的AuthenticationToken, 也就是用户凭证来验证相应的用户凭证是否正确。

 

   来看看我为了实现验证前台用户凭证和后台用户凭证而实现的AuthenticationProvider吧。

 

 

Java代码  收藏代码
  1. package com.template.security.authentication.provider;  
  2.   
  3. import com.template.security.authentication.token.BackendAuthenticationToken;  
  4. import org.springframework.security.authentication.AuthenticationProvider;  
  5. import org.springframework.security.authentication.AuthenticationServiceException;  
  6. import org.springframework.security.core.Authentication;  
  7. import org.springframework.security.core.AuthenticationException;  
  8. import org.springframework.security.core.context.SecurityContextHolder;  
  9.   
  10. /** 
  11.  * Created by IntelliJ IDEA. 
  12.  * User: Zhong Gang 
  13.  * Date: 12-11-4 
  14.  * Time: 下午11:16 
  15.  */  
  16. public class BackendAuthenticationProvider implements AuthenticationProvider {  
  17.   
  18.     @Override  
  19.     public Authentication authenticate(Authentication authentication) throws AuthenticationException {  
  20.         BackendAuthenticationToken authenticationToken = (BackendAuthenticationToken) authentication;  
  21. //        String captcha = authenticationToken.getCaptcha();  
  22. //        if (captcha.startsWith("ZZ")) {  
  23. //            throw new AuthenticationServiceException("The captcha is wrong!");  
  24. //        }  
  25.         String username = (String) authenticationToken.getPrincipal();  
  26.         String password = (String) authenticationToken.getCredentials();  
  27.   
  28.         if (username.equalsIgnoreCase("ZHONGGANG") && password.equalsIgnoreCase("123")) {  
  29.             SecurityContextHolder.getContext().setAuthentication(authenticationToken);  
  30.             return authenticationToken;  
  31.         }  
  32.         throw new AuthenticationServiceException("The username or password is not correct!");  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean supports(Class<?> authentication) {  
  37.         return BackendAuthenticationToken.class.isAssignableFrom(authentication);  
  38.     }  
  39. }  

 

 

Java代码  收藏代码
  1. package com.template.security.authentication.provider;  
  2.   
  3. import com.template.security.authentication.token.ForendAuthenticationToken;  
  4. import org.springframework.security.authentication.AuthenticationProvider;  
  5. import org.springframework.security.authentication.AuthenticationServiceException;  
  6. import org.springframework.security.core.Authentication;  
  7. import org.springframework.security.core.AuthenticationException;  
  8. import org.springframework.security.core.context.SecurityContextHolder;  
  9.   
  10. /** 
  11.  * Created by IntelliJ IDEA. 
  12.  * User: Zhong Gang 
  13.  * Date: 12-11-4 
  14.  * Time: 下午11:16 
  15.  */  
  16. public class ForendAuthenticationProvider implements AuthenticationProvider {  
  17.   
  18.     @Override  
  19.     public Authentication authenticate(Authentication authentication) throws AuthenticationException {  
  20.         ForendAuthenticationToken authenticationToken = (ForendAuthenticationToken) authentication;  
  21.         String email = authenticationToken.getEmail();  
  22.         String phone = authenticationToken.getPhone();  
  23.         if (email.endsWith("@qq.com") && phone.startsWith("139")) {  
  24.             authenticationToken.setAuthenticated(true);  
  25.             SecurityContextHolder.getContext().setAuthentication(authenticationToken);  
  26.             return authenticationToken;  
  27.         }  
  28.   
  29.         throw new AuthenticationServiceException("The email or phone is not correct!");  
  30.     }  
  31.   
  32.     @Override  
  33.     public boolean supports(Class<?> authentication) {  
  34.         return ForendAuthenticationToken.class.isAssignableFrom(authentication);  
  35.     }  
  36. }  

 

    不论是前台用户凭证验证还是后台用户凭证验证,都实现了AuthenticationProvider接口,其中的supports方法表明这个AuthenticationProvider需要对哪个类型的用户凭证进行验证。这里我只是进行了一个简单的验证,没有什么实际意义,如果你的验证需要与数据库打交道,你可以在AuthenticationProvider中注入你的服务。来看看配置文件中的相应配置信息吧。

 

 

Xml代码  收藏代码
  1. <authentication-manager alias="authenticationManager">  
  2.     <authentication-provider ref="forendAuthenticationProvider"/>  
  3.     <authentication-provider ref="backendAuthenticationProvider"/>  
  4. </authentication-manager>  
  5.   
  6. <beans:bean id="backendAuthenticationProvider"  
  7.             class="com.template.security.authentication.provider.BackendAuthenticationProvider"/>  
  8. <beans:bean id="forendAuthenticationProvider"  
  9.             class="com.template.security.authentication.provider.ForendAuthenticationProvider"/>  

Spring Security 3多用户登录实现之六 用户验证后处理

验证用户后主要有这样两种走向,一种是验证失败,一种是验证成功,验证失败后应该如何处理呢,验证成功又该如何处理呢?

 

   验证失败的处理需要实现AuthenticationFailureHandler接口,我的前台用户认证失败的处理是这样的

 

 

Java代码  收藏代码
  1. package com.template.security.authentication.handler;  
  2.   
  3. import com.template.security.shared.DirectUrlResolver;  
  4. import org.springframework.security.core.AuthenticationException;  
  5. import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import java.io.IOException;  
  11. import java.util.ArrayList;  
  12. import java.util.List;  
  13.   
  14. /** 
  15.  * Created by IntelliJ IDEA. 
  16.  * User: Zhong Gang 
  17.  * Date: 12-11-9 
  18.  * Time: 下午11:20 
  19.  */  
  20. public class MultipleAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {  
  21.     private List<DirectUrlResolver> resolvers = new ArrayList<DirectUrlResolver>();  
  22.   
  23.     @Override  
  24.     public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {  
  25.         for (DirectUrlResolver resolver : resolvers) {  
  26.             if (resolver.support(request)) {  
  27.                 String directUrl = resolver.directUrl();  
  28.                 setDefaultFailureUrl(directUrl);  
  29.             }  
  30.         }  
  31.   
  32.         super.onAuthenticationFailure(request, response, exception);  
  33.     }  
  34.   
  35.     public void setResolvers(List<DirectUrlResolver> resolvers) {  
  36.         this.resolvers = resolvers;  
  37.     }  
  38. }  

 

    验证成功的处理需要实现AuthenticationSuccessHandler接口,我的后台验证成功处理是这样的

 

 

Java代码  收藏代码
  1. package com.template.security.authentication.handler;  
  2.   
  3. import com.template.security.shared.DirectUrlResolver;  
  4. import org.springframework.security.core.Authentication;  
  5. import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import java.io.IOException;  
  11. import java.util.ArrayList;  
  12. import java.util.List;  
  13.   
  14. /** 
  15.  * Created by IntelliJ IDEA. 
  16.  * User: Zhong Gang 
  17.  * Date: 12-11-9 
  18.  * Time: 下午11:20 
  19.  */  
  20. public class MultipleAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {  
  21.     private List<DirectUrlResolver> resolvers = new ArrayList<DirectUrlResolver>();  
  22.   
  23.     @Override  
  24.     public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {  
  25.         for (DirectUrlResolver resolver : resolvers) {  
  26.             if (resolver.support(request)) {  
  27.                 String directUrl = resolver.directUrl();  
  28.                 setDefaultTargetUrl(directUrl);  
  29.             }  
  30.         }  
  31.   
  32.         super.onAuthenticationSuccess(request, response, authentication);  
  33.     }  
  34.   
  35.     public void setResolvers(List<DirectUrlResolver> resolvers) {  
  36.         this.resolvers = resolvers;  
  37.     }  
  38. }  

 

    不论是前台验证成功还是后台验证成功,前台验证失败还是后台验证失败我都有不同的处理,前台验证成功导向前台验证成功界面,后台验证成功导向后台验证成功界面, 前台验证失败导向前台登录界面, 后台验证失败导向后台登录界面,所以这里我使用了前面我书写的一个通用接口,也就是DirectUrlResolver。来看看验证处理成功或失败的配置信息。

 

 

Xml代码  收藏代码
  1. <beans:bean id="multipleAuthenticationSuccessHandler"  
  2.              class="com.template.security.authentication.handler.MultipleAuthenticationSuccessHandler">  
  3.      <beans:property name="alwaysUseDefaultTargetUrl" value="true"/>  
  4.      <beans:property name="resolvers">  
  5.          <beans:list>  
  6.              <beans:ref bean="backendAuthenticationSuccessUrlResolver"/>  
  7.              <beans:ref bean="forendAuthenticationSuccessUrlResolver"/>  
  8.          </beans:list>  
  9.      </beans:property>  
  10.  </beans:bean>  
  11.   
  12.  <beans:bean id="backendAuthenticationSuccessUrlResolver"  
  13.              class="com.template.security.shared.RequestParameterDirectUrlResolver">  
  14.      <beans:property name="parameterName" value="token"/>  
  15.      <beans:property name="pattern" value="backend"/>  
  16.      <beans:property name="directUrl" value="/backend/login/success"/>  
  17.  </beans:bean>  
  18.   
  19.  <beans:bean id="forendAuthenticationSuccessUrlResolver"  
  20.              class="com.template.security.shared.RequestParameterDirectUrlResolver">  
  21.      <beans:property name="parameterName" value="token"/>  
  22.      <beans:property name="pattern" value="forend"/>  
  23.      <beans:property name="directUrl" value="/forend/login/success"/>  
  24.  </beans:bean>  
  25.   
  26.  <beans:bean id="multipleAuthenticationFailureHandler"  
  27.              class="com.template.security.authentication.handler.MultipleAuthenticationFailureHandler">  
  28.      <beans:property name="resolvers">  
  29.          <beans:list>  
  30.              <beans:ref bean="backendAuthenticationFailureUrlResolver"/>  
  31.              <beans:ref bean="forendAuthenticationFailureUrlResolver"/>  
  32.          </beans:list>  
  33.      </beans:property>  
  34.  </beans:bean>  
  35.   
  36.  <beans:bean id="backendAuthenticationFailureUrlResolver"  
  37.              class="com.template.security.shared.RequestParameterDirectUrlResolver">  
  38.      <beans:property name="parameterName" value="token"/>  
  39.      <beans:property name="pattern" value="backend"/>  
  40.      <beans:property name="directUrl" value="/backend/login?error=1"/>  
  41.  </beans:bean>  
  42.   
  43.  <beans:bean id="forendAuthenticationFailureUrlResolver"  
  44.              class="com.template.security.shared.RequestParameterDirectUrlResolver">  
  45.      <beans:property name="parameterName" value="token"/>  
  46.      <beans:property name="pattern" value="forend"/>  
  47.      <beans:property name="directUrl" value="/forend/login?error=1"/>  
  48.  </beans:bean>  

 

    这里还需要将相应的验证Handler注入到前讲的认证处理Filter中。

 

 

0
0
分享到:
评论

相关推荐

    Spring Security in Action

    Spring Security 实践指南 Spring Security 是一个基于 Java 的安全框架,旨在提供身份验证、授权和访问控制等功能。下面是 Spring Security 的主要知识点: 一、身份验证(Authentication) 身份验证是指对用户...

    SpringSecurity.pdf

    Spring Security是一个功能强大、高度定制的安全框架,它专门用于为基于Spring的应用程序提供安全性解决方案。Spring Security架构的设计初衷是为了解决认证和授权的需求,确保应用程序的安全性。它提供了全面的安全...

    Spring Security 资料合集

    Spring Security 是一个强大的安全框架,主要用于Java应用的安全管理,它为Web应用和企业级应用提供了全面的安全服务。这个框架能够处理认证、授权以及各种安全相关的功能,帮助开发者构建安全、可扩展的应用。以下...

    SpringSecurity笔记,编程不良人笔记

    SpringSecurity是Java领域中一款强大的安全框架,主要用于Web应用程序的安全管理。它提供了全面的身份验证、授权、会话管理以及安全相关的功能,可以帮助开发者构建安全的Web应用。在本笔记中,我们将深入探讨Spring...

    spring security 完整项目实例

    Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个完整的项目实例中,我们将深入探讨Spring Security的核心概念以及如何将其应用于实际的Web应用程序开发。 首先,我们从用户、...

    Spring Cloud Gateway 整合 Spring Security 统一登录认证鉴权

    在压缩包文件`spring_gateway_security_webflux`中,可能包含了示例代码或配置文件,用于演示如何在Spring Cloud Gateway中集成Spring Security,实现统一登录认证鉴权。这些资源可以帮助开发者更快地理解和实践上述...

    springsecurity学习笔记

    在"springsecurity学习笔记"中,你可能会涉及以下主题: - Spring Security的基本配置,包括web安全配置和全局安全配置。 - 如何自定义认证和授权流程,比如实现自定义的AuthenticationProvider和...

    SpringBoot+SpringSecurity处理Ajax登录请求问题(推荐)

    SpringBoot+SpringSecurity处理Ajax登录请求问题 SpringBoot+SpringSecurity处理Ajax登录请求问题是SpringBoot开发中的一個常见问题,本文将详细介绍如何使用SpringBoot+SpringSecurity处理Ajax登录请求问题。 ...

    spring security 官方文档

    Spring Security 是一个强大的安全框架,用于为Java应用提供全面的安全管理解决方案。它是Spring生态系统的组成部分,专注于身份验证、授权和访问控制。Spring Security的核心特性包括: 1. **身份验证...

    SpringSecurity学习总结源代码

    SpringSecurity是Java开发中用于构建安全Web应用的框架,它提供了强大的身份验证、授权和访问控制功能。在本文中,我们将深入探讨SpringSecurity的核心概念、关键组件以及如何配置和使用这个框架。 首先,Spring...

    spring spring security2.5 jar

    Spring Security是Spring生态体系中的一个核心组件,主要负责应用程序的安全性,包括认证和授权。它为Web应用提供了全面的保护,防止未经授权的访问和操作。在版本2.5时,Spring Security已经是一个成熟且功能丰富的...

    最详细Spring Security学习资料(源码)

    Spring Security是一个功能强大且高度可定制的身份验证和授权框架,专门用于保护Java应用程序的安全性。它构建在Spring Framework基础之上,提供了全面的安全解决方案,包括身份验证、授权、攻击防护等功能。 Spring...

    spring security3 中文版本

    ### Spring Security 3.0.1 中文版知识点解析 #### 一、Spring Security 3.0.1 概览 ##### 1.1 Spring Security 是什么? Spring Security 是一个强大的、高度可定制的身份验证和访问控制框架。它提供了许多功能...

    安全框架Spring Security深入浅出视频教程

    视频详细讲解,需要的小伙伴自行网盘下载,链接见附件,永久有效。 首先,SSM环境中我们通过xml配置的...Springsecurity在两种不同的开发模式中使用,有经典的独立web后台管理系统,也有时下最流行的前后端分离场景。

    springsecurity原理流程图.pdf

    Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架,它是安全领域中Spring生态系统的一部分。Spring Security旨在为Java应用程序提供一个全面的安全解决方案,尤其适用于企业级应用场景。它主要...

    精彩:Spring Security 演讲PPT

    ### Spring Security 概述与应用实践 #### 一、引言 在当今互联网时代,网络安全问题日益凸显,尤其是Web应用程序的安全性受到了前所未有的关注。为了应对这些挑战,Spring Security 应运而生,成为了一个非常重要...

    Spring security认证授权

    Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,用于Java应用程序。它提供了全面的安全解决方案,包括用户认证、权限授权、会话管理、CSRF防护以及基于HTTP的访问控制。在这个例子中,我们将...

    springSecurity 实现传参

    Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,用于Java应用程序。在这个场景中,我们关注的是如何使用Spring Security实现登录验证以及在登录过程中传递参数,特别是记录并返回用户登录前的...

    SpringSecurity素材.rar

    SpringSecurity是Java领域中一款强大的安全框架,专为Spring和Spring Boot应用设计,提供全面的安全管理解决方案。在SpringBoot Web开发中,SpringSecurity扮演着核心角色,负责处理身份验证、授权以及访问控制等...

    spring security实现动态授权

    Spring Security 是一个强大的安全框架,用于为Java应用提供安全控制。在传统的权限管理中,权限配置通常硬编码在应用程序中,这使得权限调整变得困难,每次变动都需要重新部署应用。然而,通过动态授权,我们可以将...

Global site tag (gtag.js) - Google Analytics