一、搞定acegi时要注意的几个地方:
1、用户注册和删除用户时清除缓存中对应该用户的相关信息。
2、登录时附加验证码等信息的扩展以及注意密码加密方式。
3、角色表中新增的角色名必须要与配置文件中设置的匹配,否则无效。
4、设置成Method类型的资源,必须在有至少一个角色给予赋值后,其它未赋予改资源的角色才会受访问权的限制,否则,也就是当没有赋值给任何一个角色时,该资源相当于是无效的,即该资源不受访问权的限制。
5、角色表中需要有个名字为"ROLE_ANONYMOUS"的角色("ROLE"是配置文件中配置的匹配字符串),一般将首页的资源赋予给这个角色。
二、着重点
1、先看配置文件applicationContext-acegi-security.xml,附件中
2、对applicationContext-acegi-security.xml配置文件中的几点进行说明
处理登录请求的过滤器 authenticationProcessingFilter
默认的配置如下:
xml 代码
- < bean id = "authenticationProcessingFilter"
- class = "org.acegisecurity.ui.webapp.AuthenticationProcessingFilter" >
- < property name = "authenticationManager"
- ref = "authenticationManager" />
- < property name = "authenticationFailureUrl"
- value = "/login.jsp?login_error=1" />
- < property name = "defaultTargetUrl" value = "/admin/index.jsp" />
- < property name = "filterProcessesUrl"
- value = "/j_acegi_security_check" />
- < property name = "rememberMeServices" ref = "rememberMeServices" />
- bean >
我改成了如下的配置:
xml 代码
- < bean id = "authenticationProcessingFilter"
- class = "org.springside.security.filter.util.AuthenticationProcessingFilter" >
- < property name = "continueChainBeforeSuccessfulAuthentication" value = "true" > property >
- < property name = "authenticationManager"
- ref = "authenticationManager" />
- < property name = "authenticationFailureUrl"
- value = "/accessDenied.jsp" />
- < property name = "defaultTargetUrl" value = "/index.jsp" />
- < property name = "filterProcessesUrl"
- value = "/userm.do" />
- < property name = "rememberMeServices" ref = "rememberMeServices" />
- bean >
其实就是重写了acegi自带的AuthenticationProcessingFilter
因为我在用户登录的时候还附加了验证码
并且换了登录的action路径(改成了"/userm.do?method=login"),以及用户登陆的用户名和密码的名称(默认的是j_username和j_password,我改成了username和password),这些东西都在我重写的AuthenticationProcessingFilter中得到控制。附件中有完整的AuthenticationProcessingFilter代码。
java 代码
- package org.springside.security.filter.util;
- import java.io.IOException;
- import java.util.Properties;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.RequestDispatcher;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.acegisecurity.AcegiMessageSource;
- import org.acegisecurity.Authentication;
- import org.acegisecurity.AuthenticationException;
- import org.acegisecurity.AuthenticationManager;
- import org.acegisecurity.context.SecurityContextHolder;
- import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
- import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
- import org.acegisecurity.ui.AuthenticationDetailsSource;
- import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
- import org.acegisecurity.ui.WebAuthenticationDetails;
- import org.acegisecurity.ui.rememberme.NullRememberMeServices;
- import org.acegisecurity.ui.rememberme.RememberMeServices;
- import org.acegisecurity.ui.savedrequest.SavedRequest;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.struts.Globals;
- import org.apache.struts.action.ActionMessage;
- import org.apache.struts.action.ActionMessages;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.context.ApplicationEventPublisher;
- import org.springframework.context.ApplicationEventPublisherAware;
- import org.springframework.context.support.MessageSourceAccessor;
- import org.springframework.util.Assert;
- import com.yahaitt.exception.AuthenticationCodeException;
- public class AuthenticationProcessingFilter implements Filter,
- InitializingBean, ApplicationEventPublisherAware {
- public static final String ACEGI_SAVED_REQUEST_KEY = "ACEGI_SAVED_REQUEST_KEY" ;
- public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION" ;
- public static final String ACEGI_SECURITY_FORM_USERNAME_KEY = "username" ;
- public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "password" ;
- public static final String ACEGI_SECURITY_LAST_USERNAME_KEY = "ACEGI_SECURITY_LAST_USERNAME" ;
- protected final Log logger = LogFactory.getLog( this .getClass());
- private ApplicationEventPublisher eventPublisher;
- private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
- private AuthenticationManager authenticationManager;
- private String authenticationFailureUrl;
- private String defaultTargetUrl;
- private String filterProcessesUrl = getDefaultFilterProcessesUrl();
- private boolean alwaysUseDefaultTargetUrl = false ;
- private RememberMeServices rememberMeServices = new NullRememberMeServices();
- protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
- private Properties exceptionMappings = new Properties();
- private boolean continueChainBeforeSuccessfulAuthentication = false ;
- public boolean isContinueChainBeforeSuccessfulAuthentication() {
- return continueChainBeforeSuccessfulAuthentication;
- }
- public void setContinueChainBeforeSuccessfulAuthentication(
- boolean continueChainBeforeSuccessfulAuthentication) {
- this .continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
- }
- public String getDefaultFilterProcessesUrl() {
- return "/j_acegi_security_check" ;
- }
- public void destroy() {
- }
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain filterChain) throws IOException, ServletException {
- if (!(request instanceof HttpServletRequest)) {
- throw new ServletException( "Can only process HttpServletRequest" );
- }
- if (!(response instanceof HttpServletResponse)) {
- throw new ServletException( "Can only process HttpServletResponse" );
- }
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
- String username = obtainUsername(httpRequest);
- String password = obtainPassword(httpRequest);
- if (username == null ) {
- username = "" ;
- }
- if (password == null ) {
- password = "" ;
- }
- if (requiresAuthentication(httpRequest, httpResponse)) {
- Authentication authResult;
- try {
- // 加入验证码
- onPreAuthentication(httpRequest, httpResponse);
- authResult = attemptAuthentication(httpRequest);
- // UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
- // username, password);
- // setDetails(httpRequest, authRequest);
- // httpRequest.getSession().setAttribute(
- // ACEGI_SECURITY_LAST_USERNAME_KEY, username);
- // authResult = this.getAuthenticationManager().authenticate(
- // authRequest);
- // Authentication success
- // successfulAuthentication(httpRequest, httpResponse, authResult);
- //如果authResult = this.getAuthenticationManager().authenticate(authRequest);函数执行后无异常,则说明认证通过了,此时可以直接进行下轮的过滤器
- //即跳转到进入这个filter的url(user_login.jsp页面中form的action指向等,此时执行下面的filterChain.doFilter(httpRequest, httpResponse);后就能够跳转到UserMAction的login函数中执行)
- // filterChain.doFilter(httpRequest, httpResponse);
- if (continueChainBeforeSuccessfulAuthentication) {
- filterChain.doFilter(httpRequest, httpResponse);
- }
- // // 可以在此加入验证成功后的功能代码
- successfulAuthentication(httpRequest, httpResponse, authResult);
- // String targetUrl = alwaysUseDefaultTargetUrl ? null
- // : obtainFullRequestUrl(httpRequest);
- if (targetUrl == null) {
- targetUrl = getDefaultTargetUrl();
- }
- if (!targetUrl.startsWith("http://")
- && !targetUrl.startsWith("https://")) {
- targetUrl = httpRequest.getContextPath() + targetUrl;
- }
- //
- // targetUrl = request.getParameter("pagefrom");
- //
- // httpResponse.sendRedirect(httpResponse
- // .encodeRedirectURL(targetUrl));
- return ;
- } catch (AuthenticationException failed) {
- // Authentication failed
- unsuccessfulAuthentication(httpRequest, httpResponse, failed);
- // String failureUrl = exceptionMappings.getProperty(failed
- // .getClass().getName(), authenticationFailureUrl);
- // if (!failureUrl.startsWith("http://")
- // && !failureUrl.startsWith("https://")) {
- // failureUrl = httpRequest.getContextPath() + failureUrl;
- // }
- String pagefrom = request.getParameter( "pagefrom" );
- request.setAttribute( "pagefrom" , pagefrom);
- String pageURL = "/WEB-INF/pages/user_login.jsp" ;
- RequestDispatcher rd = request.getRequestDispatcher(pageURL);
- rd.forward(request, response);
- // httpResponse.sendRedirect(httpResponse
- // .encodeRedirectURL(failureUrl));
- return ;
- }
- }
- filterChain.doFilter(request, response);
- }
- public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException,
- IOException {
- String username = obtainUsername(request);
- String password = obtainPassword(request);
- if (username == null ) {
- username = "" ;
- }
- if (password == null ) {
- password = "" ;
- }
- UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
- username, password);
- setDetails(request, authRequest);
- request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,
- username);
- return this .getAuthenticationManager().authenticate(authRequest);
- }
- protected void setDetails(HttpServletRequest request,
- UsernamePasswordAuthenticationToken authRequest) {
- authRequest.setDetails( new WebAuthenticationDetails(request));
- }
- protected boolean requiresAuthentication(HttpServletRequest request,
- HttpServletResponse response) {
- String uri = request.getRequestURI();
- int pathParamIndex = uri.indexOf(';');
- if (pathParamIndex > 0 ) {
- uri = uri.substring( 0 , pathParamIndex);
- }
- String method = request.getParameter( "method" );
- boolean islogin = "login" .equals(method)? true : false ;
- return (uri.endsWith(request.getContextPath() + filterProcessesUrl) && islogin);
- }
- public void init(FilterConfig arg0) throws ServletException {
- }
- public void afterPropertiesSet() throws Exception {
- }
- public void setApplicationEventPublisher(ApplicationEventPublisher context) {
- this .eventPublisher = context;
- }
- public void setAuthenticationDetailsSource(
- AuthenticationDetailsSource authenticationDetailsSource) {
- Assert.notNull(authenticationDetailsSource,
- "AuthenticationDetailsSource required" );
- this .authenticationDetailsSource = authenticationDetailsSource;
- }
- public boolean isAlwaysUseDefaultTargetUrl() {
- return alwaysUseDefaultTargetUrl;
- }
- public void setAlwaysUseDefaultTargetUrl( boolean alwaysUseDefaultTargetUrl) {
- this .alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;
- }
- public String getAuthenticationFailureUrl() {
- return authenticationFailureUrl;
- }
- public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
- this .authenticationFailureUrl = authenticationFailureUrl;
- }
- public String getDefaultTargetUrl() {
- return defaultTargetUrl;
- }
- public void setDefaultTargetUrl(String defaultTargetUrl) {
- this .defaultTargetUrl = defaultTargetUrl;
- }
- public String getFilterProcessesUrl() {
- return filterProcessesUrl;
- }
- public void setFilterProcessesUrl(String filterProcessesUrl) {
- this .filterProcessesUrl = filterProcessesUrl;
- }
- protected String obtainPassword(HttpServletRequest request) {
- String password = request.getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY);
- // if (password != null) {
- // return MD5.toMD5(request
- // .getParameter(ACEGI_SECURITY_FORM_PASSWORD_KEY));
- // }
- return password;
- }
- protected String obtainUsername(HttpServletRequest request) {
- return request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY);
- }
- // 加入验证码
- protected void onPreAuthentication(HttpServletRequest request,
- HttpServletResponse response) throws AuthenticationException,
- IOException {
- String randNum = request.getParameter( "randNum" );
- String rand = (String) request.getSession().getAttribute( "RandNo" );
- if (rand == null || !rand.equals(randNum)) {
- throw new AuthenticationCodeException( "请输入正确的验证码!" );
- }
- }
- // 可以在此加入验证成功后的功能代码
- protected void onSuccessfulAuthentication(HttpServletRequest request,
- HttpServletResponse response, Authentication authResult)
- throws IOException {
- }
- protected void onUnsuccessfulAuthentication(HttpServletRequest request,
- HttpServletResponse response, AuthenticationException failed)
- throws IOException {
- ActionMessages errors = new ActionMessages();
- String username = request.getParameter( "username" );
- String password = request.getParameter( "password" );
- if (failed instanceof AuthenticationCodeException)
- {
- //验证码为空或出错
- errors.add( "userwrong" , new ActionMessage( "user.randno.wrong" ));
- } else if ( null ==username || "" .equals(username))
- {
- //用户名为空
- errors.add( "userwrong" , new ActionMessage( "user.username" ));
- } else if ( null ==password || "" .equals(password))
- {
- //密码为空
- errors.add( "userwrong" , new ActionMessage( "user.password" ));
- } else
- {
- //用户名或密码出错
- errors.add( "userwrong" , new ActionMessage( "user.wrong" ));
- }