自定义Spring Security Logout过滤器

时间:2011-03-28 18:03:42

标签: spring spring-security

我需要在我的spring security 3.0.5 Web应用程序中对用户进行解除身份验证(终止他们的会话),然后将重定向发送到另一个站点以通知他们注销。这在春天是否可行?如果是这样,执行这些任务的一般方法是什么?谢谢!

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;

import com.dc.api.model.Users;

public class DCSimpleUrlLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler{

    public void onLogoutSuccess(javax.servlet.http.HttpServletRequest request, 
            javax.servlet.http.HttpServletResponse response,
            Authentication authentication)
     throws java.io.IOException,
            javax.servlet.ServletException{
            Users user=null;
            Object principal = authentication.getPrincipal();
            if (principal instanceof Users) {
                user = (Users) principal;
                if(user.getType().equals(TEST)){
                    response.sendRedirect("LogoutServlet");
                }
            }
            response.sendRedirect("login.html");

}

}

java.lang.IllegalStateException
    org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:463)
    javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
    org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper.sendRedirect(SaveContextOnUpdateOrErrorResponseWrapper.java:74)
    com.dc.api.service.impl.DCSimpleUrlLogoutSuccessHandler.onLogoutSuccess(DCSimpleUrlLogoutSuccessHandler.java:24)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:100)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)

2 个答案:

答案 0 :(得分:8)

实际上,标记的“正确答案”是关于设置自定义logout success-handler,而不是LogoutFilter,而不是定义问题。

因此,如果有人想要创建自定义注销过滤器,请参阅以下代码段:

<bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <property name="filterProcessesUrl" value="/logout"/>
    <constructor-arg index="0" value="/"/>
    <constructor-arg index="1">
        <list>
            <ref bean="securityContextLogoutHandler"/>
            <!--ref bean="myLogoutHandler"/-->
        </list>
    </constructor-arg>
</bean>

这是一个默认的过滤器类,有一个默认的预定义处理程序(这一个无效的会话)。 如果您确实需要自定义注销过滤器,那么您应该更改此标准行为(子类或使用相同的接口编写自己的行为)。 另外不要忘记注册它:

    <security:http>
....
        <custom-filter position="LOGOUT_FILTER" ref="logoutFilter"/>
    </security:http>

<强>更新: 在阅读了一些Spring代码之后,我发现还有一个默认的注销处理程序 - RememberMeServices,使用接口AbstractRememberMeServices implements LogoutHandler定义。因此,如果您正在使用RememberMeServices并希望编写包含RememberMe支持的自定义过滤器,则还需要在注销处理程序列表中添加对RememberMeServices的引用。

答案 1 :(得分:6)

子类SimpleUrlLogoutSuccessHandler并覆盖onLogoutSuccess()以进行重定向。

配置注销成功处理程序,如:

<http>
  ...
  <logout success-handler-ref="myLogoutSuccessHandler"/>
</http>