自定义 Spring Security 注销过滤器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5463105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 04:24:56  来源:igfitidea点击:

Custom Spring Security Logout Filter

springspring-security

提问by c12

I need to de-authenticate a user (kill their session) within my spring security 3.0.5 web app and then send a redirect to another site to notify them of the logout. Is this possible within spring and if so what is the general approach to performing these tasks? Thanks!

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

回答by msangel

Actually the marked "correct answer" is about setting a custom logout success-handler, but not LogoutFilter, as defining in question.

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

So, if someone wants to create a custom logout filter, here is a snippet:

所以,如果有人想创建一个自定义注销过滤器,这里是一个片段:

<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>

This is a default filter class with one default predefined handler (this one invalidate session). If you really need a custom logout filter, then you should change this standard behavior (subclass this or write your own with the same interface). Also don't forget to register it:

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

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

UPDATE: After reading some spring code, I found, that there is one more default logout handler - RememberMeServices, defined with the interface AbstractRememberMeServices implements LogoutHandler. So if you are using RememberMeServicesand want to write a custom filter including RememberMe support, you also need add a reference to your RememberMeServicesin list of logout handlers.

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

回答by sourcedelica

Subclass SimpleUrlLogoutSuccessHandler and override onLogoutSuccess() to do the redirect.

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

Configure the logout success handler like:

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

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