spring 如何使用spring security手动注销用户?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5727380/
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:26:47  来源:igfitidea点击:

How to manually log out a user with spring security?

springspring-securitylogout

提问by Erik

Probably the answer is simple: How can I manually logout the currently logged in user in spring security? Is it sufficient to call:

可能答案很简单:如何在 spring security 中手动注销当前登录的用户?是否足以调用:

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

?

?

采纳答案by Piotr Müller

In Servlet 3.0 container Spring logout functionality is integrated with servlet and you just invoke logout()on your HttpServletRequest. Still need to write valid response content.

在 Servlet 3.0 容器中,Spring 注销功能与 servlet 集成在一起,您只需logout()HttpServletRequest. 仍然需要编写有效的响应内容。

According to documentation(Spring 3.2):

根据文档(Spring 3.2):

The HttpServletRequest.logout() method can be used to log the current user out.

Typically this means that the SecurityContextHolder will be cleared out, the HttpSession will be invalidated, any "Remember Me" authentication will be cleaned up, etc.

HttpServletRequest.logout() 方法可用于注销当前用户。

通常这意味着 SecurityContextHolder 将被清除,HttpSession 将失效,任何“记住我”身份验证将被清除,等等。

回答by Grzegorz Oledzki

It's hard for me to say for sure if your code is enough. However standard Spring-security's implementation of logging out is different. If you took a look at SecurityContextLogoutHandleryou would see they do:

我很难确定你的代码是否足够。但是标准的 Spring-security 的注销实现是不同的。如果你看一看,SecurityContextLogoutHandler你会看到他们这样做:

    SecurityContextHolder.clearContext();

Moreover they optionally invalidate the HttpSession:

此外,他们可以选择使 HttpSession 无效:

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

You may find more information in some other question about logging out in Spring Securityand by looking at the source code of org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler.

您可能会发现更多的信息关于Spring Security的退出在其他一些问题,并通过查看源代码org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler

回答by gibaholms

I use the same code in LogoutFilter, reusing the LogoutHandlers as following:

我在 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);
}

回答by Ritesh

You can also use SessionRegistryas:

您还可以将SessionRegistry用作:

sessionRegistry.getSessionInformation(sessionId).expireNow();

If you want to force logout in all sessions of a user then use getAllSessionsmethod and call expireNowof each session information.

如果要在用户的所有会话中强制注销,请使用每个会话信息的getAllSessions方法和调用expireNow

Edit
This requires ConcurrentSessionFilter(or any other filter in the chain), that checks SessionInformation and calls all logout handlers and then do redirect.

编辑
这需要ConcurrentSessionFilter(或链中的任何其他过滤器),检查 SessionInformation 并调用所有注销处理程序,然后进行重定向。

回答by James

To log out a user in a web application you can also redirect him to the logout page. The LogoutFilter is then doing all the work for you.

要在 Web 应用程序中注销用户,您还可以将他重定向到注销页面。然后 LogoutFilter 会为您完成所有工作。

The url of the logout page is set in the security configuration:

退出页面的url在安全配置中设置:

<sec:http ...>
  ...
  <sec:logout logout-url="/logout" logout-success-url="/login?logout_successful=1" />
  ...
</sec:http>

回答by Tiago

new SecurityContextLogoutHandler().logout(request, null, null);

new SecurityContextLogoutHandler().logout(request, null, null);

回答by loulou

Simply do like this (the ones commented by "concern you") :

只需这样做(“关注你”评论的那些):

    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
    }

回答by Nayan

Recently we had to implement logout functionality using Spring-security 3.0.5. Although this question is already answered above, I will post the complete code which would definitely help novice user like me :)

最近我们不得不使用 Spring-security 3.0.5 实现注销功能。虽然上面已经回答了这个问题,但我会发布完整的代码,这肯定会帮助像我这样的新手用户:)

Configuration in Spring-security.xml

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

Here i have created two custom classes

在这里我创建了两个自定义类

  1. XXXLogoutHandler which will implement org.springframework.security.web.authentication.logout.LogoutHandler and will override the logout() method.
  2. XXXLogoutSuccessHandler which will implement org.springframework.security.web.authentication.logout.LogoutSuccessHanlder and will override onLoguoutSuccess() method. Within the XXXLogoutSuccessHandler.onLogoutSuccess() method call the redirectStrategy.sendRedirect() method which logout the user to the particular targetURL.
  3. org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler does the task of invalidating the user session.
  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 执行使用户会话无效的任务。

Hope this would help and give the correct direction to the starter

希望这会有所帮助并为初学者提供正确的方向

Note: Intentionally have not posted code for custom implementation.

注意:故意没有发布自定义实现的代码。

回答by Hany Sakr

Right Oledzki, I am using the following for example inside my controller to logout and redirect the user to the login page in spring security 4.2.3

正确的 Oledzki,我在控制器中使用以下示例来注销并将用户重定向到 spring security 4.2.3 中的登录页面

SecurityContextHolder.clearContext();

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

return "redirect:/login";