Spring Security 实战干货:实现自定义退出登录
2021-03-29 12:25
标签:throws 登录页面 前言 and let uri 需要 类型 ssi 上一篇对 Spring Security 所有内置的 Filter 进行了介绍。今天我们来实战如何安全退出应用程序。 这个问题我们必须搞清楚!一般登录后,服务端会给用户发一个凭证。常见有以下的两种: 接下来我们来分析并实战 如何定制退出登录逻辑。首先我们要了解 通过 Spring Security 实战干货:内置 Filter 全解析 我们知道退出登录逻辑是由过滤器 我们通过对以上三个接口的实现就能实现我们自定义的退出逻辑。 我们一般不会直接操作 默认情况下 Spring Security 是基于 如果上面满足不了你的需要就需要你来定制 现在前后端分离比较多,退出后返回json。而且只有用户在线才能退出登录。否则不能进行退出操作。我们采用实现 默认情况下清除认证信息 ( 以上是我们实现的 如果我们实现了自定义的 为了方便调试我 注释掉了我们 实现的自定义登录,你可以通过 本篇 我们实现了 在 Spring Security 下的自定义退出逻辑。相对比较简单,你可以根据你的业务需要来实现你的退出逻辑。 Spring Security 实战干货:实现自定义退出登录 标签:throws 登录页面 前言 and let uri 需要 类型 ssi 原文地址:https://blog.51cto.com/14901317/25284342. 我们使用 Spring Security 登录后都做了什么
Session
客户端会存 cookie
来保存一个 sessionId
,服务端存一个 Session
。token
客户端存一个 token
串,服务端会在缓存中存一个用来校验此 token
的信息。2. 退出登录需要我们做什么
permitAll
, 只有携带对应用户的凭证才退出。3. Spring Security 中的退出登录
LogoutFilter
。3.1 LogoutFilter
LogoutFilter
来执行的。它持有三个接口类型的属性:
RequestMatcher logoutRequestMatcher
这个用来拦截退出请求的 URL
LogoutHandler handler
用来处理退出的具体逻辑LogoutSuccessHandler logoutSuccessHandler
退出成功后执行的逻辑3.2 LogoutConfigurer
LogoutFilter
,而是通过 LogoutConfigurer
来配置 LogoutFilter
。你可以通过 HttpSecurity#logout()
方法来初始化一个 LogoutConfigurer
。接下来我们来实战操作一下。3.2.1 实现自定义退出登录请求URL
LogoutConfigurer
提供了 logoutRequestMatcher(RequestMatcher logoutRequestMatcher)
、logoutUrl(Sring logoutUrl)
两种方式来定义退出登录请求的 URL
。它们作用是相同的,你选择其中一种方式即可。3.2.2 处理具体的逻辑
Session
的。LogoutConfigurer
提供了一些直接配置来满足你的需要。如下:
clearAuthentication(boolean clearAuthentication)
是否在退出时清除当前用户的认证信息deleteCookies(String... cookieNamesToClear)
删除指定的 cookies
invalidateHttpSession(boolean invalidateHttpSession)
是否移除 `HttpSession```LogoutHandler
了。3.2.3 退出成功逻辑
logoutSuccessUrl(String logoutSuccessUrl)
退出成功后会被重定向到此 URL
,你可以写一个Controller 来完成最终返回,但是需要支持 GET
请求和 匿名访问 。 通过 setDefaultTargetUrl
方法注入到 LogoutSuccessHandler
defaultLogoutSuccessHandlerFor(LogoutSuccessHandler handler, RequestMatcher preferredMatcher)
用来构造默的 LogoutSuccessHandler
我们可以通过添加多个来实现从不同 URL
退出执行不同的逻辑。LogoutSuccessHandler logoutSuccessHandler
退出成功后执行的逻辑的抽象根本接口。3.3 Spring Security 退出登录实战
LogoutHandler
和 LogoutSuccessHandler
接口这种编程的方式来配置 。退出请求的 url
依然通过 LogoutConfigurer#logoutUrl(String logoutUrl)
来定义。3.3.1 自定义 LogoutHandler
invalidateHttpSession
),和Session 失效(invalidateHttpSession
) 已经由内置的SecurityContextLogoutHandler
来完成。我们自定义的 LogoutHandler
会在SecurityContextLogoutHandler
来执行。 @Slf4j
public class CustomLogoutHandler implements LogoutHandler {
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
User user = (User) authentication.getPrincipal();
String username = user.getUsername();
log.info("username: {} is offline now", username);
}
}
LogoutHandler
。我们可以从 logout
方法的 authentication
变量中 获取当前用户信息。你可以通过这个来实现你具体想要的业务。比如记录用户下线退出时间、IP 等等。3.3.2 自定义 LogoutSuccessHandler
LogoutSuccessHandler
就不必要设置 LogoutConfigurer#logoutSuccessUrl(String logoutSuccessUrl)
了。该处理器处理后会响应给前端。你可以转发到其它控制器。重定向到登录页面,也可以自行实现其它 MediaType
,可以是 json
或者页面 @Slf4j
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
User user = (User) authentication.getPrincipal();
String username = user.getUsername();
log.info("username: {} is offline now", username);
responseJsonWriter(response, RestBody.ok("退出成功"));
}
private static void responseJsonWriter(HttpServletResponse response, Rest rest) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
ObjectMapper objectMapper = new ObjectMapper();
String resBody = objectMapper.writeValueAsString(rest);
PrintWriter printWriter = response.getWriter();
printWriter.print(resBody);
printWriter.flush();
printWriter.close();
}
}
3.3.4 自定义退出的 Spring Security 配置
http:localhost:8080/login
来登录,然后通过 http:localhost:8080/logout
测试退出。 @Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.cors()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
// .addFilterBefore(preLoginFilter, UsernamePasswordAuthenticationFilter.class)
// 登录
.formLogin().loginProcessingUrl(LOGIN_PROCESSING_URL).successForwardUrl("/login/success").failureForwardUrl("/login/failure")
.and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessHandler(new CustomLogoutSuccessHandler());
}
4. 总结
文章标题:Spring Security 实战干货:实现自定义退出登录
文章链接:http://soscw.com/index.php/essay/69508.html