Вероятно, ответ прост: как я могу вручную выйти из системы вошедшего в систему пользователя в весенней безопасности? Достаточно ли позвонить:
SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false);
?
Вероятно, ответ прост: как я могу вручную выйти из системы вошедшего в систему пользователя в весенней безопасности? Достаточно ли позвонить:
SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false);
?
В контейнере Servlet 3.0 функция выхода из Spring интегрирована с сервлетом, и вы просто вызываете logout()
на своем HttpServletRequest
. Все еще нужно написать действительное содержание ответа.
Согласно документации (весна 3.2):
Метод HttpServletRequest.logout() можно использовать для выхода текущего пользователя из системы.
Обычно это означает, что SecurityContextHolder будет очищен, HttpSession станет недействительным, любая аутентификация «Запомнить меня» будет очищена и т. д.
org.apache.catalina.connector.Request#logout
для Spring 3.1.2 / Grails 2.2.0. Нет такой ошибки с clearContext()
.
- person Pavel Vlasov; 22.10.2014
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
.
Я использую тот же код в 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);
}
Вы также можете использовать SessionRegistry как:
sessionRegistry.getSessionInformation(sessionId).expireNow();
Если вы хотите принудительно выйти из системы во всех сеансах пользователя, используйте метод getAllSessions
и вызовите expireNow
информации о каждом сеансе.
Изменить
Для этого требуется ConcurrentSessionFilter
(или любой другой фильтр в цепочке), который проверяет SessionInformation и вызывает все обработчики выхода, а затем выполняет перенаправление.
Чтобы выйти из системы пользователя в веб-приложении, вы также можете перенаправить его на страницу выхода. Тогда LogoutFilter сделает всю работу за вас.
URL-адрес страницы выхода задается в конфигурации безопасности:
<sec:http ...>
...
<sec:logout logout-url="/logout" logout-success-url="/login?logout_successful=1" />
...
</sec:http>
Просто сделайте так (те, которые прокомментированы "беспокоят вас"):
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
}
Недавно нам пришлось реализовать функцию выхода из системы с помощью 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"/>
Здесь я создал два пользовательских класса
Надеюсь, это поможет и даст правильное направление стартеру.
Примечание. Код для пользовательской реализации намеренно не опубликован.
Правильно, Oledzki, я использую следующее, например, внутри своего контроллера, чтобы выйти из системы и перенаправить пользователя на страницу входа в весеннюю безопасность 4.2.3.
SecurityContextHolder.clearContext();
if(session != null)
session.invalidate();
return "redirect:/login";