In the last step of our custom registration flow, users will gain an authentication token (access_token and refresh_token) after entering their new password.
Having that we can initialize a logged-in instance of Keycloak javascript class. However; this won’t set the sso cookies (KEYCLOAK_IDENTITY, …).
Is there a solution to set these cookies or can we generate a login-actions/authenticate URL and post the user’s credentials in a post request (custom login form)?
Thank you for the suggestion
After some changes to handle the CORS issue, now the /SSO end-point return the expected Cookies; However, they are sent without expiry date which means they are not persistence.
Looking into keycloak implementation of AuthenticationManager.java (Line 664) you can see the following code if (session != null && session.isRememberMe()) { maxAge = realm.getSsoSessionMaxLifespanRememberMe() > 0 ? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan(); }
Did you have same issue? Any suggestion how can I change cookies lifespan?
We don’t use “Remember Me” and I currently don’t know how Session#rememberMe can be set to true besides by the user checking the “Remember me” checkbox on the login page.
In our use case, we set the SSO cookies with an access token obtained through token exchange and direct access grants, and I have no idea if it is possible to set rememberMe when a session is created this way and unfortunately I don’t have the chance to try and find out at the moment
Of course I’d be interested if you find out something!
Nevermind, the problem was that no storageProviders are found and hence the user is always null.
We now just use the following line to obtain the user:
UserModel user = keycloakSession.users().getUserById(token.getSubject(), realm);
And this is how we handle Cors using org.keycloak.services.resources.Cors:
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/sso")
public Response sso(@Context final HttpRequest request) {
// ... stuff to set the cookie ...
Cors cors = Cors.add(request, Response.noContent()).auth()
.allowedMethods("GET")
.allowedOrigins(token)
.auth().exposedHeaders();
return cors.build();
Also, we needed to add an @OPTIONS endpoint:
@OPTIONS
@Path("/sso")
public Response preflight(@Context final HttpRequest request) {
return Cors.add(request, Response.ok()).auth().preflight()
.allowAllOrigins()
.allowedMethods("GET", "OPTIONS").build();
}
So, now we are also have the issue with the rememberMe / session-dropping on page reload.
I tried copying the AuthenticationManager.createLoginCookie(...) to set maxAge but the cookies are not set anyway The response header looks fine, but they do not show up in devtools > Application > Cookies.
I was missing the credentials: 'include' flag for the fetch call on the frontend. For me it’s working now (including a persistent session on page refresh and without hacking a maxAge for the cookies).
Thank you Tikko for the suggestion, It works!
Regarding CORS I tried to implement your approach however I’m missing the module dependencies. Here’s my current module addition command.
Thanks for your solution. It works ! I use it to establish a session in a embedded browser (javafx) using access token previously obtained by keycloak desktop adapter and authorization grant flow.
But, is there any security issues implied by this implementation ?
Unfortunately my SPI is not displayed in the admin. But if I add my .jar in jboss/keycloak/standalone/deployments, then I see my SPI in the admin. But with the error mentioned above.
I am new to the Java/Keycloak world. I am happy for any help.