2011-03-28 57 views
3

我需要在我的弹簧安全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) 

回答

6

子类SimpleUrlLogoutSuccessHandler并重写onLogoutSuccess()做重定向。

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

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

关于为什么我会在重定向上获得非法状态的任何想法? – c12 2011-03-28 22:58:05

+0

这通常意味着某些输出在重定向之前发送。 – sourcedelica 2011-03-29 00:47:26

+0

IllegalStateException是由调用两次重定向导致的。 'response.sendRedirect(“https://secure05.pilot.principal.com/shared/members/corp/LogoutServlet”);''和'response.sendRedirect(“/ dreamcatcher/auth/login.html”);'' – Jonathan 2013-07-30 02:41:54

7

其实,标有“正确的答案”是关于设置自定义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> 

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