Как вручную выйти из системы с помощью весенней безопасности?

Вероятно, ответ прост: как я могу вручную выйти из системы вошедшего в систему пользователя в весенней безопасности? Достаточно ли позвонить:

SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false); 

?


person Erik    schedule 20.04.2011    source источник
comment
Большое спасибо за ваши ответы, ребята, я проверю их.   -  person Erik    schedule 20.04.2011


Ответы (8)


В контейнере Servlet 3.0 функция выхода из Spring интегрирована с сервлетом, и вы просто вызываете logout() на своем HttpServletRequest. Все еще нужно написать действительное содержание ответа.

Согласно документации (весна 3.2):

Метод HttpServletRequest.logout() можно использовать для выхода текущего пользователя из системы.

Обычно это означает, что SecurityContextHolder будет очищен, HttpSession станет недействительным, любая аутентификация «Запомнить меня» будет очищена и т. д.

person Piotr Müller    schedule 28.01.2014
comment
Наличие NPE в реализации Tomcat 7 org.apache.catalina.connector.Request#logout для Spring 3.1.2 / Grails 2.2.0. Нет такой ошибки с clearContext(). - person Pavel Vlasov; 22.10.2014
comment
@PavelVlasov Я считаю, что это какая-то ошибка в конфигурации spring, почитайте о SecurityContextHolder. - person Piotr Müller; 19.06.2015
comment
После request.logout() у меня все еще есть авторизованный пользователь в SecurityContextHolder.getContext().getAuthentication() - person Grigory Kislin; 25.10.2017

Мне сложно сказать наверняка, достаточно ли вашего кода. Однако стандартная реализация выхода из системы Spring-security отличается. Если вы взглянете на SecurityContextLogoutHandler, вы увидите, что они делают:

    SecurityContextHolder.clearContext();

Более того, они могут аннулировать HttpSession:

    if (invalidateHttpSession) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
    }

Вы можете найти дополнительную информацию в другом вопросе о выходе из Spring Security и посмотрев исходный код org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler.

person Grzegorz Oledzki    schedule 20.04.2011
comment
Вы также можете удалить файл cookie Rememberme, если он установлен. - person sourcedelica; 20.04.2011

Я использую тот же код в LogoutFilter, повторно используя LogoutHandlers следующим образом:

public static void myLogoff(HttpServletRequest request, HttpServletResponse response) {
    CookieClearingLogoutHandler cookieClearingLogoutHandler = new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
    SecurityContextLogoutHandler securityContextLogoutHandler = new SecurityContextLogoutHandler();
    cookieClearingLogoutHandler.logout(request, response, null);
    securityContextLogoutHandler.logout(request, response, null);
}
person gibaholms    schedule 12.12.2012
comment
+1 из-за CookieClearingLogoutHandler, иначе пользователь сможет снова войти в систему, если у него есть файл cookie Rememberme. Обратите внимание, что для этого класса требуется spring 3.1 - person redochka; 20.05.2014

Вы также можете использовать SessionRegistry как:

sessionRegistry.getSessionInformation(sessionId).expireNow();

Если вы хотите принудительно выйти из системы во всех сеансах пользователя, используйте метод getAllSessions и вызовите expireNow информации о каждом сеансе.

Изменить
Для этого требуется ConcurrentSessionFilter (или любой другой фильтр в цепочке), который проверяет SessionInformation и вызывает все обработчики выхода, а затем выполняет перенаправление.

person Ritesh    schedule 20.04.2011

Чтобы выйти из системы пользователя в веб-приложении, вы также можете перенаправить его на страницу выхода. Тогда LogoutFilter сделает всю работу за вас.

URL-адрес страницы выхода задается в конфигурации безопасности:

<sec:http ...>
  ...
  <sec:logout logout-url="/logout" logout-success-url="/login?logout_successful=1" />
  ...
</sec:http>
person James    schedule 31.08.2012
comment
Это не сработало для меня. Это не так просто, как вы предлагаете. Есть еще подробности конфигурации? - person djangofan; 30.11.2012
comment
Для этого не должно быть никакой другой конфигурации, необходимой для работы. Вы просто перенаправляете пользователя на URL-адрес вида example.com/yourctx/logout. - person James; 30.11.2012
comment
У меня это заработало, но мне пришлось перезапустить Tomcat, чтобы он начал работать. - person djangofan; 30.11.2012

Просто сделайте так (те, которые прокомментированы "беспокоят вас"):

    Authentication auth = SecurityContextHolder.getContext().getAuthentication(); // concern you

    User currUser = userService.getUserById(auth.getName()); // some of DAO or Service...

    SecurityContextLogoutHandler ctxLogOut = new SecurityContextLogoutHandler(); // concern you

    if( currUser == null ){
        ctxLogOut.logout(request, response, auth); // concern you
    }
person loulou    schedule 18.04.2013

Недавно нам пришлось реализовать функцию выхода из системы с помощью Spring-security 3.0.5. Хотя на этот вопрос уже дан ответ выше, я опубликую полный код, который определенно поможет начинающему пользователю, такому как я :)

Конфигурация в Spring-security.xml

 <http auto-config="false" lowercase-comparisons="false" use-expressions="true">
     <custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />
 </http>

<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <beans:constructor-arg name="logoutSuccessHandler" ref="xxxLogoutSuccessHandler" />
    <beans:constructor-arg name="handlers">
        <beans:list>
            <beans:ref bean="securityContextLogoutHandler"/>
            <beans:ref bean="xxxLogoutHandler"/>
        </beans:list>
    </beans:constructor-arg>
    <beans:property name="filterProcessesUrl" value="/logout"/>
</beans:bean>
<beans:bean id="XXXLogoutSuccessHandler" class="com.tms.dis.sso.XXXLogoutSuccessHandler"/>
<beans:bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
    <beans:property name="invalidateHttpSession" value="true"/>
</beans:bean>
<beans:bean id="XXXLogoutHandler" class="com.tms.dis.sso.XXXLogoutHandler"/>

Здесь я создал два пользовательских класса

  1. XXXLogoutHandler, который реализует org.springframework.security.web.authentication.logout.LogoutHandler и переопределяет метод logout().
  2. XXXLogoutSuccessHandler, который реализует org.springframework.security.web.authentication.logout.LogoutSuccessHanlder и переопределяет метод onLoguoutSuccess(). В методе XXXLogoutSuccessHandler.onLogoutSuccess() вызовите метод redirectStrategy.sendRedirect(), который выводит пользователя из системы на конкретный targetURL.
  3. org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler выполняет задачу аннулирования сеанса пользователя.

Надеюсь, это поможет и даст правильное направление стартеру.

Примечание. Код для пользовательской реализации намеренно не опубликован.

person Nayan    schedule 24.10.2013

Правильно, Oledzki, я использую следующее, например, внутри своего контроллера, чтобы выйти из системы и перенаправить пользователя на страницу входа в весеннюю безопасность 4.2.3.

SecurityContextHolder.clearContext();

if(session != null)
    session.invalidate();

return "redirect:/login";
person Hany Sakr    schedule 26.09.2017