springside 玩转acegi

一、搞定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.         }   
  318.    

你可能感兴趣的:(UI,jsp,servlet,Security,Acegi)