Closed tasso94 closed 1 month ago
OAuth2 works with tokens for authentication and Spring Security is fully supporting this. Tokens have a lifetime until they are valid, this is the exp
claim, for instance: exp=2024-09-09T16:13:05Z
.
This lifetime is configurable in the identity providers, including the usage of refresh tokens. Cognito & OKTA default is 1h.
General security recommendation is to use short-lived access tokens combined with long-lived refresh tokens. With refresh tokens applications can renew access tokens but they can be revoked and the refresh mechanism won't work when the user is not logged in anymore in SSO.
Articles:
OpenID Connect Session Management 1.0 allows the ability to log out the end user at the Client by having the Provider make an API call to the Client. This is referred to as - Spring Security feature: https://github.com/spring-projects/spring-security/issues/7845 - Spring Security docs: https://docs.spring.io/spring-security/reference/reactive/oauth2/login/logout.html#configure-provider-initiated-oidc-logout
Outcome:
iat=2024-09-13T11:34:21Z
Session contains the access token with 5mins lifespan:
SecurityContext: 2024-09-13T12:34:21Z
HttpSession: 2024-09-13T11:39:21.859091Z
server.servlet.session.timeout: 10m
and this will invalidate the session but only after inactivity. Once the session is expired a new token would be reissued.Resources:
ExpiredTokenFilter
to handle this problem. The filter uses Spring classes so it's fairly straight forward.Outcome:
AuthorizeTokenFilter
filter that re-authorizes the token if needed using the refresh_token grant.OAuth2AuthorizedClientRepository
defines where and how to store tokens. Default implementations is HttpSessionOAuth2AuthorizedClientRepository. This could be extended similarly than our cache time to live.AuthorizeTokenFilter
and rely only on the provider settings for token lifetime.Make sure no expired access token is used in the application. Our filter logs the expiration, you can activate debug log in application.yaml
with:
logging:
level:
org.camunda.bpm.spring.boot.starter.security.oauth2: DEBUG
offline_access
in application.yaml scopes.
Authorize failed: could not re-authorize expired access token
.Authorize failed: ...
error will appear.Verified on camunda-bpm-run-ee-7.22.0-20240919.175253-98
Environment (Required on creation)
Camunda Run with OAuth2.
Description (Required on creation; please attach any relevant screenshots, stacktraces, log files, etc. to the ticket)
When logging out from Cognito:
https://camunda-run.auth.us-east-1.amazoncognito.com/logout?response_type=code&client_id=$CLIENT_ID&scope=openid&redirect_uri=http://localhost:8080/
Replace
$CLIENT_ID
with what you can find inspring.security.oauth2.client.registration
.... the user is still logged in to the web apps.
Steps to reproduce (Required on creation)
Observed Behavior (Required on creation)
User is still logged in.
Expected behavior (Required on creation)
User should be logged out.
Root Cause (Required on prioritization)
Not clear. I guess the authentication is cached forever. Maybe we need to implement something like https://github.com/camunda/camunda-bpm-platform/issues/3146 here as well.
Solution Ideas
Hints
It only works when logging out from Cognito first and using the OAuth2 Spring Security Logout URL second: http://localhost:8080/logout
Like this, the session cookie is cleared.
However, this is not acceptable because it requires another User action. When the identity provider forces a logout or removes the user, Camunda should check regularly if the user is still valid.
Links
Breakdown
Dev2QA handover