英文:
Spring authorization server: logout via Postman
问题
我设法使用新的Spring授权服务器设置了一个OAuth2身份提供者。
为了执行一些测试,我使用了Postman - OAuth2身份验证流程,我能够轻松获取JWT令牌。
令牌刷新也可以直接使用,非常完美。
使用获取的令牌,我能够保护另一个Spring Boot项目上的API,尽管经历了相当长时间的反复试验过程。
问题是,我不知道如何通过Postman测试注销过程。
是否有人可以帮助我,提供任何示例的链接?
在此提前表示感谢。
我期望在此过程之后,令牌会被使无效,以便不能再用于保护API端点。
英文:
I've managed to setup an OAuth2 identity provider using new Spring Authorization Server.
To execute some tests, I used Postman - OAuth2 Authentication flow and I was able to get
a JWT token without problems.
Token Refresh also works perfectly out of the box.
With the acquired token, I was able to secure an Api on another Spring Boot project,
after a quite long trial-and-error process.
Problem is, I've no idea about how to test logout process via Postman.
Is there anyone who could help me, providing a link to any example ?
Thank you in advance.
I'd expect the token to be invalidated after the process, so that it cannot be used anymore to secure API endpoints.
答案1
得分: 1
RP Initiated Logout是一种在OIDC授权服务器上使用户会话无效的标准方法。并非所有的“OIDC”授权服务器在注销方面都符合规范,但我认为Spring的授权服务器是符合的。请阅读(简短的)规范,了解如何从.well-known/openid-configuration
中找到注销终端URI,以及如何构建注销请求(方法、参数等)。有了这些元素,您应该能够构建您的Postman请求来使用户在OP上的会话无效。
JWT是不可变的,你无法使其无效(即使你可以,也不能保证你更新了所有现有的副本)。它从发行时开始到过期为止是有效的。没有例外。
您可以使以下内容无效:
- 客户端的用户会话。通常伴随着令牌的删除。
- 授权服务器上的用户会话。当您这样做时,应该不可能:
- 使用注销前发放的刷新令牌获取新的访问令牌(即使该刷新令牌仍然有效)
- 检查注销前发放的访问令牌(即使访问令牌仍然有效)
如果你不能信任客户端在用户登出时删除访问令牌,或者访问令牌的有效期不够短以接受在登出后访问的风险,那么您可能需要将资源服务器从JWT解码切换到令牌审查。是的,你可以审查JWT,但是审查实际上不高效。
顺便说一句,如果你不能信任客户端处理访问令牌的方式,那么你面临的安全问题比用户登出后访问令牌的剩余生存期更大...
对第一个评论的详细回答
登录和登出是客户端的责任,而不是资源服务器的责任,REST API是资源服务器(应该依赖于spring-boot-starter-oauth2-resource-server
而不是spring-boot-starter-oauth2-client
)。
我敢打赌你面临的问题不是由于访问令牌仍然有效,而是用户会话仍然有效,因此用户登录是静默进行的,因此调用上面链接中描述的授权服务器上的end_session_endpoint
(是的,你应该跟随链接并阅读内容)。
您有几个操作要执行:
- 确保您的REST API被配置为资源服务器(而不是客户端),并从中删除登录和注销。我已经写了一些关于这个主题的教程。
- 为用户登录和注销配置一个OAuth2客户端。可以是:
- Angular应用程序本身,使用类似angular-auth-oidc-client这样的库。该库有很好的文档,使用起来很容易,只需跟随链接并查阅文档。
- 一个用于前端的后端(在您的服务器上保持Angular应用程序的会话的中间件,处理登录和注销,从授权服务器获取令牌,将这些令牌存储在会话中,然后在将请求从浏览器转发到API之前用访问令牌替换会话cookie)。 如果配置为OAuth2客户端并使用
TokenRelay
过滤器,spring-cloud-gateway
可以用作BFF。我在上述链接中的特定教程集合中有一个完整的BFF实现,其中包括sprin g-cloud-gateway
(和Angular)。
无论您选择在浏览器中公开的OAuth2客户端还是在您的服务器上保密的OAuth2客户端,都由它负责触发RP启动的注销以使授权服务器上的用户会话无效
-
我提供的Angular库可以做到这一点
-
如果您选择了一个带有spring的OAuth2客户端实现,您可以配置一个
OidcClientInitiatedLogoutSuccessHandler
(或者在响应式应用中使用OidcClientInitiatedServerLogoutSuccessHandler
),在客户端上的注销后将用户重定向到授权服务器,以便两个会话都被无效化
英文:
RP Initiated Logout is a standard way to invalidate user session on an authorization server with OIDC. Not all "OIDC" authorization servers comply with the spec when it comes to logout, but I think Spring's one does. Read the (short) spec to figure out how to find the logout endpoint URI from the .well-known/openid-configuration
as well as how to build the logout request (method, params, etc.). With this elements, you should be able to build your Postman request to invalidate user session on the OP.
JWTs are immutable, you can't invalidate it (and even if you could, you'd never have the guaranty that you updated all the existing copies). It is valid from its issuance and until it expires. Period.
What you can invalidate are user sessions on:
- the client. This usually goes with token deletion
- the authorization server. When you do so, it should not be possible to:
- get new access tokens with a refresh token issued before the logout (even if this refresh token is still valid)
- introspect an access token issued before the logout (even if the access token is still valid)
If you can't trust the client to delete the access token when the user logs out and if the access tokens are not short lived enough to accept the risk of an access after logout, then you might have to switch the resource server from JWT decoding to token introspection. Yes, you can introspect a JWT, but no, introspection is not efficient at all.
As a side note, if you can't trust how client handles access tokens, you have a much bigger security issue than the remaining lifespan of access tokens after user logout...
Developed answer to the 1st comment
Login and logout are the responsibility of the client, not of the resource server, and REST API are resource servers (it should depend on spring-boot-starter-oauth2-resource-server
and not of spring-boot-starter-oauth2-client
.
My bet is the issue you are facing is not due to the access-token still being valid but that user sessions are still valid and that user login is done silently because of that => call the end_session_endpoint
on the authorization server as described in the spec linked above (yes, you should follow the link and read the content).
You have several actions to take:
- make sure your REST API is configured as a resource server (and not as a client) and remove login and logout from there. I have written quite a few tutorials on that subject.
- configure an OAuth2 client for users login and logout. It could be:
- the Angular application itself using a lib like angular-auth-oidc-client. This lib is well documented and easy to use, just follow the link and browse to the doc.
- a Backend For Frontend (a middleware on your server keeping sessions for the Angular app, handling login and logout, fetching tokens from the authorization server, storing this tokens in session and then replacing session cookies with access token before forwarding a request from the browser to the API).
spring-cloud-gateway
can be used as BFF if configured as OAuth2 client and using theTokenRelay
filter. I have a complete BFF implementation withspring-cloud-gateway
(and Angular) in this specific tutorial from the collection linked above.
Whatever implementation you choose for the OAuth2 client (public in the browser or confidential on your server), it is its responsibility to trigger the RP Initiated Logout to invalidate the user session on the authorization server
-
the Angular lib I linked does it
-
if you choose an OAuth2 client implementation with spring, you can configure an
OidcClientInitiatedLogoutSuccessHandler
(orOidcClientInitiatedServerLogoutSuccessHandler
in a reactive app) to redirect the user to the authorization server after the logout on your client so that both sessions are invalidated
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论