2011-03-28 56 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的引用。