`
阅读更多

一、搞定acegi时要注意的几个地方:

1、用户注册和删除用户时清除缓存中对应该用户的相关信息。

2、登录时附加验证码等信息的扩展以及注意密码加密方式。

3、角色表中新增的角色名必须要与配置文件中设置的匹配,否则无效。

4、设置成Method类型的资源,必须在有至少一个角色给予赋值后,其它未赋予改资源的角色才会受访问权的限制,否则,也就是当没有赋值给任何一个角色时,该资源相当于是无效的,即该资源不受访问权的限制。

5、角色表中需要有个名字为"ROLE_ANONYMOUS"的角色("ROLE"是配置文件中配置的匹配字符串),一般将首页的资源赋予给这个角色。

二、着重点

1、先看配置文件applicationContext-acegi-security.xml,附件中

 2、对applicationContext-acegi-security.xml配置文件中的几点进行说明

处理登录请求的过滤器 authenticationProcessingFilter

默认的配置如下:

xml 代码
  1. < bean   id = "authenticationProcessingFilter"   
  2.          class = "org.acegisecurity.ui.webapp.AuthenticationProcessingFilter" >   
  3.          < property   name = "authenticationManager"   
  4.              ref = "authenticationManager"   />   
  5.          < property   name = "authenticationFailureUrl"   
  6.              value = "/login.jsp?login_error=1"   />   
  7.          < property   name = "defaultTargetUrl"   value = "/admin/index.jsp"   />   
  8.          < property   name = "filterProcessesUrl"   
  9.              value = "/j_acegi_security_check"   />   
  10.          < property   name = "rememberMeServices"   ref = "rememberMeServices"   />   
  11.      bean >   

 

我改成了如下的配置:

xml 代码
  1. < bean   id = "authenticationProcessingFilter"   
  2.          class = "org.springside.security.filter.util.AuthenticationProcessingFilter" >   
  3.          < property   name = "continueChainBeforeSuccessfulAuthentication"   value = "true" > property >   
  4.          < property   name = "authenticationManager"   
  5.              ref = "authenticationManager"   />   
  6.          < property   name = "authenticationFailureUrl"   
  7.              value = "/accessDenied.jsp"   />   
  8.          < property   name = "defaultTargetUrl"   value = "/index.jsp"   />   
  9.          < property   name = "filterProcessesUrl"   
  10.              value = "/userm.do"   />   
  11.          < property   name = "rememberMeServices"   ref = "rememberMeServices"   />   
  12.      bean >   

 

其实就是重写了acegi自带的AuthenticationProcessingFilter

因为我在用户登录的时候还附加了验证码

并且换了登录的action路径(改成了"/userm.do?method=login"),以及用户登陆的用户名和密码的名称(默认的是j_username和j_password,我改成了username和password),这些东西都在我重写的AuthenticationProcessingFilter中得到控制。附件中有完整的AuthenticationProcessingFilter代码。

 

java 代码
  1. package  org.springside.security.filter.util;   
  2.   
  3. import  java.io.IOException;   
  4. import  java.util.Properties;   
  5.   
  6. import  javax.servlet.Filter;   
  7. import  javax.servlet.FilterChain;   
  8. import  javax.servlet.FilterConfig;   
  9. import  javax.servlet.RequestDispatcher;   
  10. import  javax.servlet.ServletException;   
  11. import  javax.servlet.ServletRequest;   
  12. import  javax.servlet.ServletResponse;   
  13. import  javax.servlet.http.HttpServletRequest;   
  14. import  javax.servlet.http.HttpServletResponse;   
  15.   
  16. import  org.acegisecurity.AcegiMessageSource;   
  17. import  org.acegisecurity.Authentication;   
  18. import  org.acegisecurity.AuthenticationException;   
  19. import  org.acegisecurity.AuthenticationManager;   
  20. import  org.acegisecurity.context.SecurityContextHolder;   
  21. import  org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;   
  22. import  org.acegisecurity.providers.UsernamePasswordAuthenticationToken;   
  23. import  org.acegisecurity.ui.AuthenticationDetailsSource;   
  24. import  org.acegisecurity.ui.AuthenticationDetailsSourceImpl;   
  25. import  org.acegisecurity.ui.WebAuthenticationDetails;   
  26. import  org.acegisecurity.ui.rememberme.NullRememberMeServices;   
  27. import  org.acegisecurity.ui.rememberme.RememberMeServices;   
  28. import  org.acegisecurity.ui.savedrequest.SavedRequest;   
  29. import  org.apache.commons.logging.Log;   
  30. import  org.apache.commons.logging.LogFactory;   
  31. import  org.apache.struts.Globals;   
  32. import  org.apache.struts.action.ActionMessage;   
  33. import  org.apache.struts.action.ActionMessages;   
  34. import  org.springframework.beans.factory.InitializingBean;   
  35. import  org.springframework.context.ApplicationEventPublisher;   
  36. import  org.springframework.context.ApplicationEventPublisherAware;   
  37. import  org.springframework.context.support.MessageSourceAccessor;   
  38. import  org.springframework.util.Assert;   
  39.   
  40. import  com.yahaitt.exception.AuthenticationCodeException;   
  41.   
  42. public   class  AuthenticationProcessingFilter  implements  Filter,   
  43.         InitializingBean, ApplicationEventPublisherAware {   
  44.      public   static   final  String ACEGI_SAVED_REQUEST_KEY =  "ACEGI_SAVED_REQUEST_KEY" ;   
  45.      public   static   final  String ACEGI_SECURITY_LAST_EXCEPTION_KEY =  "ACEGI_SECURITY_LAST_EXCEPTION" ;   
  46.        
  47.      public   static   final  String ACEGI_SECURITY_FORM_USERNAME_KEY =  "username" ;   
  48.      public   static   final  String ACEGI_SECURITY_FORM_PASSWORD_KEY =  "password" ;   
  49.        
  50.      public   static   final  String ACEGI_SECURITY_LAST_USERNAME_KEY =  "ACEGI_SECURITY_LAST_USERNAME" ;   
  51.        
  52.      protected   final  Log logger = LogFactory.getLog( this .getClass());   
  53.   
  54.      private  ApplicationEventPublisher eventPublisher;   
  55.      private  AuthenticationDetailsSource authenticationDetailsSource =  new  AuthenticationDetailsSourceImpl();   
  56.      private  AuthenticationManager authenticationManager;   
  57.   
  58.      private  String authenticationFailureUrl;   
  59.      private  String defaultTargetUrl;   
  60.      private  String filterProcessesUrl = getDefaultFilterProcessesUrl();   
  61.      private   boolean  alwaysUseDefaultTargetUrl =  false ;   
  62.   
  63.      private  RememberMeServices rememberMeServices =  new  NullRememberMeServices();   
  64.      protected  MessageSourceAccessor messages = AcegiMessageSource.getAccessor();   
  65.      private  Properties exceptionMappings =  new  Properties();   
  66.      private   boolean  continueChainBeforeSuccessfulAuthentication =  false ;   
  67.   
  68.      public   boolean  isContinueChainBeforeSuccessfulAuthentication() {   
  69.          return  continueChainBeforeSuccessfulAuthentication;   
  70.     }   
  71.   
  72.      public   void  setContinueChainBeforeSuccessfulAuthentication(   
  73.              boolean  continueChainBeforeSuccessfulAuthentication) {   
  74.          this .continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;   
  75.     }   
  76.   
  77.      public  String getDefaultFilterProcessesUrl() {   
  78.          return   "/j_acegi_security_check" ;   
  79.     }   
  80.        
  81.      public   void  destroy() {   
  82.     }   
  83.        
  84.   
  85.        
  86.      public   void  doFilter(ServletRequest request, ServletResponse response,   
  87.             FilterChain filterChain)  throws  IOException, ServletException {   
  88.          if  (!(request  instanceof  HttpServletRequest)) {   
  89.              throw   new  ServletException( "Can only process HttpServletRequest" );   
  90.         }   
  91.          if  (!(response  instanceof  HttpServletResponse)) {   
  92.              throw   new  ServletException( "Can only process HttpServletResponse" );   
  93.         }   
  94.            
  95.         HttpServletRequest httpRequest = (HttpServletRequest) request;   
  96.         HttpServletResponse httpResponse = (HttpServletResponse) response;   
  97.   
  98.         String username = obtainUsername(httpRequest);   
  99.         String password = obtainPassword(httpRequest);   
  100.          if  (username ==  null ) {   
  101.             username =  "" ;   
  102.         }   
  103.          if  (password ==  null ) {   
  104.             password =  "" ;   
  105.         }   
  106.            
  107.            
  108.            
  109.          if  (requiresAuthentication(httpRequest, httpResponse)) {   
  110.             Authentication authResult;   
  111.              try  {   
  112.                  // 加入验证码   
  113.                 onPreAuthentication(httpRequest, httpResponse);   
  114.                 authResult = attemptAuthentication(httpRequest);   
  115.   
  116. //              UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(   
  117. //                      username, password);   
  118. //              setDetails(httpRequest, authRequest);   
  119. //              httpRequest.getSession().setAttribute(   
  120. //                      ACEGI_SECURITY_LAST_USERNAME_KEY, username);   
  121. //              authResult = this.getAuthenticationManager().authenticate(   
  122. //                      authRequest);   
  123.                  // Authentication success   
  124. //              successfulAuthentication(httpRequest, httpResponse, authResult);   
  125.                  //如果authResult = this.getAuthenticationManager().authenticate(authRequest);函数执行后无异常,则说明认证通过了,此时可以直接进行下轮的过滤器   
  126.                  //即跳转到进入这个filter的url(user_login.jsp页面中form的action指向等,此时执行下面的filterChain.doFilter(httpRequest, httpResponse);后就能够跳转到UserMAction的login函数中执行)   
  127. //              filterChain.doFilter(httpRequest, httpResponse);   
  128.                    
  129.                  if  (continueChainBeforeSuccessfulAuthentication) {   
  130.                     filterChain.doFilter(httpRequest, httpResponse);   
  131.                 }   
  132.                    
  133.                    
  134.                    
  135.                    
  136. //              // 可以在此加入验证成功后的功能代码   
  137.                 successfulAuthentication(httpRequest, httpResponse, authResult);   
  138. //              String targetUrl = alwaysUseDefaultTargetUrl ? null   
  139. //                      : obtainFullRequestUrl(httpRequest);   
  140. ////                if (targetUrl == null) {   
  141. ////                    targetUrl = getDefaultTargetUrl();   
  142. ////                }   
  143. ////                if (!targetUrl.startsWith("http://")   
  144. ////                        && !targetUrl.startsWith("https://")) {   
  145. ////                    targetUrl = httpRequest.getContextPath() + targetUrl;   
  146. ////                }   
  147. //                 
  148. //              targetUrl = request.getParameter("pagefrom");   
  149. //                 
  150. //              httpResponse.sendRedirect(httpResponse   
  151. //                      .encodeRedirectURL(targetUrl));   
  152.                  return ;   
  153.             }  catch  (AuthenticationException failed) {   
  154.                  // Authentication failed   
  155.                 unsuccessfulAuthentication(httpRequest, httpResponse, failed);   
  156. //              String failureUrl = exceptionMappings.getProperty(failed   
  157. //                      .getClass().getName(), authenticationFailureUrl);   
  158. //              if (!failureUrl.startsWith("http://")   
  159. //                      && !failureUrl.startsWith("https://")) {   
  160. //                  failureUrl = httpRequest.getContextPath() + failureUrl;   
  161. //              }   
  162.                    
  163.                 String pagefrom = request.getParameter( "pagefrom" );   
  164.                 request.setAttribute( "pagefrom" , pagefrom);   
  165.                 String pageURL =  "/WEB-INF/pages/user_login.jsp" ;   
  166.                 RequestDispatcher rd = request.getRequestDispatcher(pageURL);   
  167.                 rd.forward(request, response);   
  168.                    
  169. //              httpResponse.sendRedirect(httpResponse   
  170. //                      .encodeRedirectURL(failureUrl));   
  171.                  return ;   
  172.             }   
  173.         }   
  174.   
  175.         filterChain.doFilter(request, response);   
  176.     }   
  177.   
  178.      public  Authentication attemptAuthentication(HttpServletRequest request)  throws  AuthenticationException,   
  179.             IOException {   
  180.         String username = obtainUsername(request);   
  181.         String password = obtainPassword(request);   
  182.          if  (username ==  null ) {   
  183.             username =  "" ;   
  184.         }   
  185.          if  (password ==  null ) {   
  186.             password =  "" ;   
  187.         }   
  188.         UsernamePasswordAuthenticationToken authRequest =  new  UsernamePasswordAuthenticationToken(   
  189.                 username, password);   
  190.         setDetails(request, authRequest);   
  191.         request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,   
  192.                 username);   
  193.          return   this .getAuthenticationManager().authenticate(authRequest);   
  194.     }   
  195.   
  196.      protected   void  setDetails(HttpServletRequest request,   
  197.             UsernamePasswordAuthenticationToken authRequest) {   
  198.         authRequest.setDetails( new  WebAuthenticationDetails(request));   
  199.     }   
  200.   
  201.      protected   boolean  requiresAuthentication(HttpServletRequest request,   
  202.             HttpServletResponse response) {   
  203.         String uri = request.getRequestURI();   
  204.          int  pathParamIndex = uri.indexOf(';');   
  205.          if  (pathParamIndex >  0 ) {   
  206.             uri = uri.substring( 0 , pathParamIndex);   
  207.         }   
  208.            
  209.         String method = request.getParameter( "method" );   
  210.          boolean  islogin =  "login" .equals(method)? true : false ;   
  211.   
  212.          return  (uri.endsWith(request.getContextPath() + filterProcessesUrl) && islogin);   
  213.     }   
  214.   
  215.      public   void  init(FilterConfig arg0)  throws  ServletException {   
  216.     }   
  217.   
  218.      public   void  afterPropertiesSet()  throws  Exception {   
  219.     }   
  220.   
  221.      public   void  setApplicationEventPublisher(ApplicationEventPublisher context) {   
  222.          this .eventPublisher = context;   
  223.     }   
  224.   
  225.      public   void  setAuthenticationDetailsSource(   
  226.             AuthenticationDetailsSource authenticationDetailsSource) {   
  227.         Assert.notNull(authenticationDetailsSource,   
  228.                  "AuthenticationDetailsSource required" );   
  229.          this .authenticationDetailsSource = authenticationDetailsSource;   
  230.     }   
  231.   
  232.      public   boolean  isAlwaysUseDefaultTargetUrl() {   
  233.          return  alwaysUseDefaultTargetUrl;   
  234.     }   
  235.   
  236.      public   void  setAlwaysUseDefaultTargetUrl( boolean  alwaysUseDefaultTargetUrl) {   
  237.          this .alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;   
  238.     }   
  239.   
  240.      public  String getAuthenticationFailureUrl() {   
  241.          return  authenticationFailureUrl;   
  242.     }   
  243.   
  244.      public   void  setAuthenticationFailureUrl(String authenticationFailureUrl) {   
  245.          this .authenticationFailureUrl = authenticationFailureUrl;   
  246.     }   
  247.   
  248.      public  String getDefaultTargetUrl() {   
  249.          return  defaultTargetUrl;   
  250.     }   
  251.   
  252.      public   void  setDefaultTargetUrl(String defaultTargetUrl) {   
  253.          this .defaultTargetUrl = defaultTargetUrl;   
  254.     }   
  255.   
  256.      public  String getFilterProcessesUrl() {   
  257.          return  filterProcessesUrl;   
  258.     }   
  259.   
  260.      public   void  setFilterProcessesUrl(String filterProcessesUrl) {   
  261.          this .filterProcessesUrl = filterProcessesUrl;   
  262.     }   
  263.   
  264.      protected  String obtainPassword(HttpServletRequest request) {   
  265.            
  266.         String password = request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY);   
  267. //      if (password != null) {   
  268. //          return MD5.toMD5(request   
  269. //                  .getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY));   
  270. //      }   
  271.          return  password;   
  272.     }   
  273.        
  274.      protected  String obtainUsername(HttpServletRequest request) {          
  275.          return  request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY);   
  276.     }   
  277.   
  278.      // 加入验证码   
  279.      protected   void  onPreAuthentication(HttpServletRequest request,   
  280.             HttpServletResponse response)  throws  AuthenticationException,   
  281.             IOException {   
  282.         String randNum = request.getParameter( "randNum" );   
  283.         String rand = (String) request.getSession().getAttribute( "RandNo" );   
  284.          if  (rand ==  null  || !rand.equals(randNum)) {   
  285.              throw   new  AuthenticationCodeException( "请输入正确的验证码!" );   
  286.         }   
  287.     }   
  288.   
  289.      // 可以在此加入验证成功后的功能代码   
  290.      protected   void  onSuccessfulAuthentication(HttpServletRequest request,   
  291.             HttpServletResponse response, Authentication authResult)   
  292.              throws  IOException {       
  293.     }   
  294.   
  295.      protected   void  onUnsuccessfulAuthentication(HttpServletRequest request,   
  296.             HttpServletResponse response, AuthenticationException failed)   
  297.              throws  IOException {   
  298.         ActionMessages errors =  new  ActionMessages();   
  299.         String username = request.getParameter( "username" );   
  300.         String password = request.getParameter( "password" );   
  301.          if (failed  instanceof  AuthenticationCodeException)   
  302.         {   
  303.              //验证码为空或出错   
  304.             errors.add( "userwrong" , new  ActionMessage( "user.randno.wrong" ));   
  305.         } else   if ( null ==username ||  "" .equals(username))   
  306.         {   
  307.              //用户名为空   
  308.             errors.add( "userwrong" , new  ActionMessage( "user.username" ));   
  309.         } else   if ( null ==password ||  "" .equals(password))   
  310.         {   
  311.              //密码为空   
  312.             errors.add( "userwrong" , new  ActionMessage( "user.password" ));   
  313.         } else   
  314.         {   
  315.              //用户名或密码出错   
  316.             errors.add( "userwrong" , new  ActionMessage( "user.wrong" ));   
  317.         }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics