Пользовательский фильтр выхода из Spring Security

Мне нужно деаутентифицировать пользователя (убить его сеанс) в моем веб-приложении Spring Security 3.0.5, а затем отправить перенаправление на другой сайт, чтобы уведомить их о выходе из системы. Возможно ли это в течение весны, и если да, то каков общий подход к выполнению этих задач? Спасибо!

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)

person c12    schedule 28.03.2011    source источник


Ответы (2)


Подкласс SimpleUrlLogoutSuccessHandler и переопределение onLogoutSuccess() для перенаправления.

Настройте обработчик успешного выхода из системы, например:

<http>
  ...
  <logout success-handler-ref="myLogoutSuccessHandler"/>
</http>
person sourcedelica    schedule 28.03.2011
comment
какие-нибудь идеи о том, почему я должен получить нелегальное состояние при перенаправлении? - person c12; 29.03.2011
comment
это обычно означает, что некоторый вывод был отправлен до перенаправления. - person sourcedelica; 29.03.2011
comment
IllegalStateException было вызвано двойным вызовом перенаправления. response.sendRedirect("https://secure05.pilot.principal.com/shared/members/corp/LogoutServlet"); и response.sendRedirect("/dreamcatcher/auth/login.html"); - person Jonathan; 30.07.2013

На самом деле помеченный «правильный ответ» касается установки пользовательского 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 в список обработчиков выхода.

person msangel    schedule 27.10.2013