最近在做项目的时候发现,使用Spring Security OAuth2作单点登录的时候,当客户端退出了,再次进入到服务端登录页面的时候,直接按之前的账号登录了。需要的逻辑应该是:站点1登录后,站点2能不输入用户名密码直接登录;当其中一个站点退出后,需要输入用户名密码重新登录。
方案一、通过SecurityContextLogoutHandler登出
在客户端的WebSecurityConfigurerAdapter中:
@Override protected void configure(HttpSecurity http) throws Exception { http .logout() .logoutSuccessUrl("http://your-auth-server/oauth/exit"); }
在服务端中:
@RequestMapping("oauth/exit") public void exit(HttpServletRequest request, HttpServletResponse response) { new SecurityContextLogoutHandler().logout(request, null, null); try { System.out.println(request.getHeader("referer")); response.sendRedirect(request.getHeader("referer")); } catch (IOException e) { e.printStackTrace(); } }
注:当http跳转到https的时候是没有referer的取到的是空的。
方案二、通过tokenServices进行退出
在服务端修改
@Autowired ConsumerTokenServices tokenServices; @GetMapping("/tokens/revoke/{tokenId:.*}") @ResponseBody public String revokeToken(@PathVariable String tokenId) { tokenServices.revokeToken(tokenId); return tokenId; }
或者
@FrameworkEndpoint public class RevokeTokenEndpoint { @Autowired @Qualifier("consumerTokenServices") ConsumerTokenServices consumerTokenServices; @DeleteMapping("/oauth/token") @ResponseBody public String revokeToken(String access_token) { if (consumerTokenServices.revokeToken(access_token)){ return "注销成功"; }else{ return "注销失败"; } } }