HI,Michal Vavrik has opened the following PR:Let me describe the current situation first.Right now, Quarkus OIDC is completely stateless, it keeps all the tokens it acquires during the authorization code flow in the session cookie, which is now also encrypted by default.This aligns well with the cloud native and the general web scalability strategies.It has some, arguably, minor costs:* cookie encryption, done by default, has its cost, and unless users manage their own encryption keys, they may get warnings of the weak encryption if the fallback secret keys used to to encrypt the cookie such as client id
private static final String ID_TOKEN_PREFIX = "idToken.";
private static final String ACCESS_TOKEN_PREFIX = "accessToken.";
private static final String REFRESH_TOKEN_PREFIX = "refreshToken.";
@Override
public Uni<String> createTokenState(RoutingContext routingContext, OidcTenantConfig oidcConfig,
AuthorizationCodeTokens tokens, OidcRequestContext<String> requestContext) {
Session session = routingContext.session();
if (session == null) {
return noSession();
}
String id = UUID.randomUUID().toString(); // to avoid predictable keys, not terribly important
session.put(ID_TOKEN_PREFIX + id, tokens.getIdToken());
session.put(ACCESS_TOKEN_PREFIX + id, tokens.getAccessToken());
session.put(REFRESH_TOKEN_PREFIX + id, tokens.getRefreshToken());
return Uni.createFrom().item(id);
}
@Override
public Uni<AuthorizationCodeTokens> getTokens(RoutingContext routingContext, OidcTenantConfig oidcConfig, String tokenState, OidcRequestContext<AuthorizationCodeTokens> requestContext) {
Session session = routingContext.session();
if (session == null) {
return noSession();
}
String idToken = session.get(ID_TOKEN_PREFIX + tokenState);
String accessToken = session.get(ACCESS_TOKEN_PREFIX + tokenState);
String refreshToken = session.get(REFRESH_TOKEN_PREFIX + tokenState);
return Uni.createFrom().item(new AuthorizationCodeTokens(idToken, accessToken, refreshToken));
}
@Override
public Uni<Void> deleteTokens(RoutingContext routingContext, OidcTenantConfig oidcConfig, String tokenState, OidcRequestContext<Void> requestContext) {
Session session = routingContext.session();
if (session == null) {
return noSession();
}
session.remove(ID_TOKEN_PREFIX + tokenState);
session.remove(ACCESS_TOKEN_PREFIX + tokenState);
session.remove(REFRESH_TOKEN_PREFIX + tokenState);
return Uni.createFrom().voidItem();
}
private static <T> Uni<T> noSession() {
return Uni.createFrom().failure(new UnsupportedOperationException("No active session or support for sessions disabled"));
}
}
--
You received this message because you are subscribed to the Google Groups "Quarkus Development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quarkus-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAMsYBfUZ_gYTu_16NXXSP_5pfkbRhmtp8apoqYY001Sj%3D%2BM1%2Bg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/048f9225-4684-48e6-abe7-5260104351fcn%40googlegroups.com.
Hi,I've been meaning to reply on this thread for a few weeks, but I keep getting distracted...
Anyway, I've been meaning to articulate one thing that I find incredibly important: SESSIONS ARE FINE. Let's use sessions.
To that end, I've been working on Quarkus support for Vert.x Web sessions, which I believe is now ready for review: https://github.com/quarkusio/quarkus/pull/36310 In that PR, sessions can be stored in memory, in Redis, or in Infinispan.
I intentionally don't support storing session data in a cookie, because 1. I think it's a bad idea in general,
2. the Vert.x Web session cookie implementation has limitations (the session cookie is signed but not encrypted, so not a good idea for sensitive data,
and it is just a single cookie and the data store to it are Base64 encoded, so there's a limit of roughly 2.5 KB of data).
session.put(id, tokens);
session.get(id, AuthorizationCodeTokens.class);
or at least
(AuthorizationCodeTokens)session.get(id);where `AuthorizationCodeTokens` implement some interface like SessionState, turning 3 tokens into a single string and parsing 3 tokens back into the bean ?
Ideas? Thoughts? I'd also welcome any reviews on the sessions PR itself, even though that's unrelated to this thread :-)
Here is a question, in addition to what Michal asked, since we have 3 tokens to manage, I guess it should be all be done atomically, I would not mind having an option to write:session.put(id, tokens);session.get(id, AuthorizationCodeTokens.class);
or at least(AuthorizationCodeTokens)session.get(id);where `AuthorizationCodeTokens` implement some interface like SessionState, turning 3 tokens into a single string and parsing 3 tokens back into the bean ?How does it look to you ?
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CAMsYBfV80Z-ghia%2BLW9Ftf4AQrbALFCoZuLqSHTdamDowLhF0Q%40mail.gmail.com.
Great question! Unfortunately, if you flush manually, Vert.x Web won't persist session data automatically at the time when response is being written. So explicit flushing in the token state manager would mean users would also have to flush explicitly, if they use the session.I tried to find a way how to make session storing synchronous with response writing, but I couldn't figure it out. Maybe it's possible, I'm no expert on Vert.x Web.I'm afraid I don't have a better answer at the moment
To view this discussion on the web visit https://groups.google.com/d/msgid/quarkus-dev/CALbocOm8Pv2PQtu_eJmOLut4TDjGDLJ-9Qsgs%2BO1wosNgq6qZQ%40mail.gmail.com.