扩展acegi以支持验证码等

 在acegi中的登陆页面:
<form action="<c:url value="j_acegi_security_check"/>" method="POST">
登陆的请求是发给/ j_acegi_security_check,在我们的系统中往往要在登陆中做一些登陆前和登陆后的操作。如记录用户的行为,加入验证码等。
在acegi的配置文件中加入以下的过滤器:
<bean id="filterChainProxy"
class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
通过改写authenticationProcessingFilter可以实现以上目的:
<bean id="authenticationProcessingFilter"
class="org.artemis.manager.auth.AuthenticationProcessingFilter">
<property name="authenticationManager"
ref="authenticationManager" />
<!-- 认证失败后,重定向的url -->
<property name="authenticationFailureUrl"
value="/login.jsp?login_error=1" />
<!-- 认证成功后,重定向的url -->
<property name="defaultTargetUrl" value="/" />
<!-- 该过滤器拦截的url,通常是/j_acegi_security_check,和登录页面(login.jsp)的登录表单的action相同 -->
<property name="filterProcessesUrl"
value="/j_acegi_security_check" />
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>

package org.artemis.manager.auth;
…………………………
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 = "j_username";
    public static final String ACEGI_SECURITY_FORM_PASSWORD_KEY = "j_password";
    public static final String ACEGI_SECURITY_LAST_USERNAME_KEY = "ACEGI_SECURITY_LAST_USERNAME";

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 {
            //加入验证码
                if(!onPreAuthentication(httpRequest, httpResponse)){
                    httpRequest.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,
                            username);
                throw new AuthenticationCodeException("请输入正确的验证码!");
                }

                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
                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;
    }
    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;
    }
    httpResponse.sendRedirect(httpResponse.encodeRedirectURL(failureUrl));
                return;
            }
        }
   
        filterChain.doFilter(request, response);
}

public Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response)
    throws AuthenticationException, IOException{
String username = obtainUsername(request);
        String password = obtainPassword(request);
       // System.out.println("username: "+username +"     passward:"+password) ;
        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);
        }

        return uri.endsWith(request.getContextPath() + filterProcessesUrl);
    }


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 boolean onPreAuthentication(HttpServletRequest request, HttpServletResponse response)
     throws AuthenticationException, IOException {
String randNum=request.getParameter("randNum");
String rand=(String)request.getSession().getAttribute("rand");
if(rand.equals(randNum)){
return true;
}
return false;
}
     //可以在此加入验证成功后的功能代码
protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
     Authentication authResult) throws IOException {}
protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
     AuthenticationException failed) throws IOException {}

protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        Authentication authResult) throws IOException {    
        //logger.info("Authentication success: " + authResult.toString());
        SecurityContextHolder.getContext().setAuthentication(authResult);
        onSuccessfulAuthentication(request, response, authResult);
        rememberMeServices.loginSuccess(request, response, authResult);
        // Fire event
        if (this.eventPublisher != null) {
            eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
        }
}
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException {
        SecurityContextHolder.getContext().setAuthentication(null);
        //logger.info("Updated SecurityContextHolder to contain null Authentication");
        try {
            request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed);
        } catch (Exception ignored) {}
        onUnsuccessfulAuthentication(request, response, failed);
        rememberMeServices.loginFail(request, response);
}
public static String obtainFullRequestUrl(HttpServletRequest request) {
        SavedRequest savedRequest = (SavedRequest) request.getSession()
                                                          .getAttribute(ACEGI_SAVED_REQUEST_KEY);
        return (savedRequest == null) ? null : savedRequest.getFullRequestUrl();
    }
public Properties getExceptionMappings() {
return exceptionMappings;
}
public void setExceptionMappings(Properties exceptionMappings) {
this.exceptionMappings = exceptionMappings;
}
public MessageSourceAccessor getMessages() {
return messages;
}
public void setMessages(MessageSourceAccessor messages) {
this.messages = messages;
}
public RememberMeServices getRememberMeServices() {
return rememberMeServices;
}
public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
}
public ApplicationEventPublisher getEventPublisher() {
return eventPublisher;
}
public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public AuthenticationDetailsSource getAuthenticationDetailsSource() {
return authenticationDetailsSource;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
}


如何编写验证码由于篇幅问题在此不多说了。在doFilter方法中我们加入onPreAuthentication,通过比较用户输入的验证码 和存在session中的验证码,如果相同才进行下一步的验证操作,否则返回登陆页面做出相应的提示。登陆成功后可以在 successfulAuthentication方法中加入一些登陆后操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值