Spring Security-21-退出登录

退出登录的功能,Spring Security 也提供了默认的实现, 接口是 /logout, 直接访问 http://www.pinzhi365.com/logout 接口效果如下:
image

这里会挑战到 /authentication/require?logout 这个请求里面,原因是默认的注销完成之后是跳转到登录页的,而我们的登录页是配置的 /authentication/require 后面的 logout 参数表示是从注销跳转过来的

默认的退出登录的处理逻辑如下:

  • 使当前 session 失效
  • 清除与当前用户相关的 remember-me 记录
  • 清空当前的 SecurityContext
  • 重定向到登录页

基本配置

BrowserSecurityConfig 中可以对退出登录做一些常用的配置

1
2
3
4
5
6
.and()
.logout()
.logoutUrl("/singnOut")
.logoutSuccessUrl("signOut.html")
.logoutSuccessHandler()
.deleteCookies("JSESSIONID")

  • logoutUrl(): 退出登录请求的 url ,通过这个配置可以替换默认的 /logout
  • logoutSuccessUrl(): 退出成功后的跳转路径
  • logoutSuccessHandler(): 退出成功后调用的控制器,这个和 logoutSuccessUrl() 是互斥的,配置了handler之后上面的方法就不生效了
  • deleteCookies(): 删除客户端的指定的 cookie

logoutSuccessHandler 配置

下面重点看一下 logoutSuccessHandler 的配置,有时候我们的退出登录的逻辑还想加一些额外的功能,比如记录日志等等, 就可以实现 LogoutSuccessHandler
新建类 MyLogoutSuccessHandler 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Slf4j
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {

private String logOutSuccessUrl;

public MyLogoutSuccessHandler(String logOutSuccessUrl) {
this.logOutSuccessUrl = logOutSuccessUrl;
}

private ObjectMapper objectMapper = new ObjectMapper();

@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
log.info("注销成功.....");

// 判断用户有没有配置注销成功页, 有的话做跳转,没有的话返回json提示
if (StringUtils.isBlank(logOutSuccessUrl)) {
Map<String, Object> map = new HashMap<>(1);
map.put("message", "注销成功");
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(map));
} else {
response.sendRedirect(logOutSuccessUrl);
}
}

}

这里就是判断了一下,有没有指定注销成功后的跳转,如果有就重定向,没有的话就返回 json 格式的提示信息

BrowserSecurityBeanConfig 中,把这个类注入到Spring容器中.

1
2
3
4
5
@Bean
@ConditionalOnMissingBean(LogoutSuccessHandler.class)
public LogoutSuccessHandler logoutSuccessHandler(){
return new MyLogoutSuccessHandler(securityProperties.getBrowser().getLogOutSuccessUrl());
}

这里就需要在浏览器的配置中加一个

1
2
3
4
/**
* 注销成功后的跳转路径
*/
private String logOutSuccessUrl;

这里不需要给默认值,然后 BrowserSecurityConfig 最终的配置如下:

1
2
3
4
5
6
7
@Autowired
private LogoutSuccessHandler logoutSuccessHandler;

.and()
.logout()
.logoutUrl(securityProperties.getBrowser().getLogOutUrl())
.logoutSuccessHandler(logoutSuccessHandler)

本文代码传送门