如何使用弹簧安全手动注销用户?

也许答案很简单: 如何在春季安全中手动注销当前登录的用户? 是否足以称之为:

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

104293 次浏览

我很难确定你的代码是否足够。然而,标准 Spring 安全性的注销实现是不同的。如果你看一下 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的源代码

你也可以使用 会话注册处作为:

sessionRegistry.getSessionInformation(sessionId).expireNow();

如果您想在用户的所有会话中强制注销,那么使用 getAllSessions方法并调用每个会话信息的 expireNow

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

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

注销页面的 URL 在安全配置中设置:

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

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

简单地这样做(那些“关心你”的评论) :

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

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

  1. XXXLogoutHandler,它将实现 org.springframework.security.web.entication.logout.LogoutHandler 并覆盖 logout ()方法。
  2. 将实现 org.springframework.security.web.entication.logout。并将重写 onLoguoutSuccess ()方法。在 XXXLogoutSuccess Handler.onLogoutSuccess ()方法中调用 redirectStrategies y.sendRedirect ()方法,该方法将用户注销到特定的 targetURL。
  3. SecurityContextLogoutHandler 执行使用户会话无效的任务。

希望这将有所帮助,并给发动机正确的方向

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

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

根据 文件 (Spring 3.2) :

可以使用 HttpServletRequest.logout ()方法登出当前用户。

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

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

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

SecurityContextHolder.clearContext();


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


return "redirect:/login";

在您的 控制器 > > signOut 方法 不要返回「/注销」中,但是在 Spring 安全上下文中重定向到/logout 方法: return "redirect:/logout";

非常简单,手动注销弹簧安全, 只需利用 Servlet 请求本身。 例如:

@PostMapping("/manualLogout")
public String customLogut(Model models, HttpServletRequest request) throws ServletException
{
request.logout();
return "redirect:/";
}

谢谢你的问题。