一、客户端退出调用认证中心/logout服务
这种方式是客户端先退出,然后再退出认证中心。
方法1:集成WebSecurityConfigurerAdapter,重写方法如下(推荐这种方式,退出干净简单)
@Override
protected void configure(HttpSecurity http) throws Exception {
http.logout().logoutSuccessUrl("认证中心/logout服务地址");
}
方法2:提供服务,先清除本地登录信息,再重定向到认证中心/logout服务
@GetMapping("/api/logout")
public String doLogout(HttpServletRequest request, HttpServletResponse response) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {//清除认证
new SecurityContextLogoutHandler().logout(request, response, authentication);
}
// 请求认证中心/logout
return "redirect:认证中心地址/logout?" + request.getQueryString();
}
二、认证中心退出
方式1、仿写TokenEndpoint使token失效
@FrameworkEndpoint
public class RevokeTokenEndpoint {
@Autowired
@Qualifier("consumerTokenServices")
ConsumerTokenServices consumerTokenServices;
@RequestMapping(method = RequestMethod.DELETE, value = "/oauth/token")
@ResponseBody
public String revokeToken(String access_token) {
if (consumerTokenServices.revokeToken(access_token)){
return "注销成功";
}else{
return "注销失败";
}
}
}
方式2、通过tokenStore清除token
@Autowired
private TokenStore tokenStore;
/**
* 移除access_token和refresh_token
*
* @param access_token
*/
@DeleteMapping(value = "/remove_token", params = "access_token")
public void removeToken(Principal principal, String access_token) {
OAuth2AccessToken accessToken = tokenStore.readAccessToken(access_token);
if (accessToken != null) {
// 移除access_token
tokenStore.removeAccessToken(accessToken);
// 移除refresh_token
if (accessToken.getRefreshToken() != null) {
tokenStore.removeRefreshToken(accessToken.getRefreshToken());
}
}
}
以上退出方式,不能实现多个客户端同时退出。
多个客户端同时退出思路,如下图,根据令牌获取到要退出的用户,再根据用户查找在所有注册系统中的令牌,依次调用注册系统本地的销毁会话和令牌的服务:
参考: