问题描述
@GetMapping("/logout")
public String getlogoutPage(HttpServletRequest request,HttpServletResponse response){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null)
new SecurityContextlogoutHandler().logout(request,response,authentication);
return "redirect:/login";
}
我实际上是在和邮递员一起做测试
下一个 url 请求身份验证 ("/example") 但当注销时,我仍然可以使用相同的令牌访问此 url,这是不对的。
解决方法
您无法真正注销 JWT 令牌,或者不像使用不透明令牌那样。使 JWT 有效的是其签名的正确性以及用于控制它的公共证书及其到期时间。 只要满足这两个条件,令牌就会有效。从基于 JWT 的系统的传统注销通常包括简单地删除客户端的令牌。
如果发生安全漏洞,您可以轮换用于生成 JWT 的密钥,但这会注销系统中的每个人,并且不可能作为每个用户的策略。
如果您想在服务器端处理它,您可以创建一个 JWT 拒绝列表,添加您要注销的令牌,并检查每个请求是否该令牌在列表中。请注意如何实现这一点以避免系统中的主要开销(使用被拒绝的令牌存储过期时间并定期清理它)。
如果您的系统分布有一个身份验证机构和多个不同的消费者,如果没有正确完成,这些消费者只会在本地“修复”注销。这意味着在某一点上遇到麻烦。你也应该考虑到这一点
使用 JWT 的一组很好的规则是:
- 不要将它们存储在任何您无法轻松移除它们并无法有效进行客户端注销的地方。
- 具有较短的到期时间并经常刷新它们。
- 根据您的安全需求,经常轮换用于生成 JWT 的密钥
- 制定应急计划来处理纯 JWT 无法处理的一些用例:更改密码、立即阻止用户...
如果您无法处理这些安全性权衡,您应该考虑转向不透明的令牌,这种令牌可以在不破坏模型的情况下轻松撤销。