Spring 当授权服务器没有访问或刷新令牌时,OAuth2Sso 仍然可以登录用户
Spring OAuth2Sso can still login user when authorization server has no access or refresh token
我正在尝试使用 spring OAuth2 注销用户。我有一个带有 @EnableOAuth2Sso
注释的服务器和一个带有 @EnableAuthorizationServer
注释的不同服务器。
Sso 服务器使用 authorization_code
流程让用户登录并有一个注销端点,该端点反过来联系授权服务器以摆脱用户的访问和刷新令牌。
调用时,这些标记将被删除,因为它们不再出现在 mongodb 中,但只要我刷新页面(连接到 Sso 服务器),我就会再次自动登录,作为授权服务器创建一个新的访问和刷新令牌。
我怀疑我的 Sso 服务器仍然有一个有效的授权码,允许它从授权服务器请求新的令牌,但我找不到授权服务器在哪里管理这些授权码。有谁知道这些存储在哪里以及我如何使这些授权码无效?还是我完全走错了路?
update:我发现问题确实与 dur 所建议的会话有关。当我在浏览器中删除 Sso 服务器的会话 cookie 时,我必须重新通过授权服务器进行身份验证。不过,我无法让 Sso 服务器销毁我的 cookie。我已经尝试通过以下方式手动循环 cookie 并使它们过期(注意我使用的是 Kotlin):
@RequestMapping("/logout",
method = [RequestMethod.GET]
)
@ResponseBody
fun redirectToLogout(request: HttpServletRequest) : RedirectView{
...
val uri = authServerInstance.uri.normalize()
val redirectView = RedirectView()
redirectView.url = "$uri/auth/logout"
request.cookies.forEach {
it.maxAge = 0
}
...
return redirectView
}
我还尝试通过以下方式使会话无效:
@RequestMapping("/logout",
method = [RequestMethod.GET]
)
@ResponseBody
fun redirectToLogout(request: HttpServletRequest) : RedirectView{
...
val uri = authServerInstance.uri.normalize()
val redirectView = RedirectView()
redirectView.url = "$uri/auth/logout"
request.session.invalidate()
...
return redirectView
}
在这两种情况下,SSO 都会尝试使会话失效,然后向授权服务器发送请求以使用户的访问和刷新令牌失效,但不知何故会话 cookie 并未失效。
SSO 服务器可以很好地删除其会话 cookie。我在问题的示例中通过 Netflix Zuul 重定向到授权服务器的注销端点,这基本上意味着在授权服务器上时仍然使用 Sso 服务器的会话 cookie,这意味着授权服务器无法销毁最初从授权服务器上的身份验证页面重定向时创建的会话 cookie。
所以为了解决这个问题,我现在直接重定向到授权服务器,这样它就可以销毁它的会话 cookie。
我正在尝试使用 spring OAuth2 注销用户。我有一个带有 @EnableOAuth2Sso
注释的服务器和一个带有 @EnableAuthorizationServer
注释的不同服务器。
Sso 服务器使用 authorization_code
流程让用户登录并有一个注销端点,该端点反过来联系授权服务器以摆脱用户的访问和刷新令牌。
调用时,这些标记将被删除,因为它们不再出现在 mongodb 中,但只要我刷新页面(连接到 Sso 服务器),我就会再次自动登录,作为授权服务器创建一个新的访问和刷新令牌。
我怀疑我的 Sso 服务器仍然有一个有效的授权码,允许它从授权服务器请求新的令牌,但我找不到授权服务器在哪里管理这些授权码。有谁知道这些存储在哪里以及我如何使这些授权码无效?还是我完全走错了路?
update:我发现问题确实与 dur 所建议的会话有关。当我在浏览器中删除 Sso 服务器的会话 cookie 时,我必须重新通过授权服务器进行身份验证。不过,我无法让 Sso 服务器销毁我的 cookie。我已经尝试通过以下方式手动循环 cookie 并使它们过期(注意我使用的是 Kotlin):
@RequestMapping("/logout",
method = [RequestMethod.GET]
)
@ResponseBody
fun redirectToLogout(request: HttpServletRequest) : RedirectView{
...
val uri = authServerInstance.uri.normalize()
val redirectView = RedirectView()
redirectView.url = "$uri/auth/logout"
request.cookies.forEach {
it.maxAge = 0
}
...
return redirectView
}
我还尝试通过以下方式使会话无效:
@RequestMapping("/logout",
method = [RequestMethod.GET]
)
@ResponseBody
fun redirectToLogout(request: HttpServletRequest) : RedirectView{
...
val uri = authServerInstance.uri.normalize()
val redirectView = RedirectView()
redirectView.url = "$uri/auth/logout"
request.session.invalidate()
...
return redirectView
}
在这两种情况下,SSO 都会尝试使会话失效,然后向授权服务器发送请求以使用户的访问和刷新令牌失效,但不知何故会话 cookie 并未失效。
SSO 服务器可以很好地删除其会话 cookie。我在问题的示例中通过 Netflix Zuul 重定向到授权服务器的注销端点,这基本上意味着在授权服务器上时仍然使用 Sso 服务器的会话 cookie,这意味着授权服务器无法销毁最初从授权服务器上的身份验证页面重定向时创建的会话 cookie。
所以为了解决这个问题,我现在直接重定向到授权服务器,这样它就可以销毁它的会话 cookie。