I'm developing a web application powered by HTMX for the client-side and Quarkus for the server-side. Quarkus supports various authentication mechanism, I've chosen OIDC Authorization Grant Flow for this project. I ended up configuring Quarkus and Keycloak applications to implement the flow.
As I try to access a protected resource as expected authorization grant flow is fired, and I end up being authenticated and granted with the requested resource, but wait, here is the moment, with next ajax request fired from granted resources my request is being re-authenticated again, and consequently fails with CORS error
Access to XMLHttpRequest at 'http://localhost:32806/realms/reactive-todos-realm/protocol/openid-connect/auth?response_type=code&client_id=reactive-todos-service&scope=openid&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fapi%2Fv1%2Ftodo&state=cab72361-ae2a-49a5-8780-1e742004cec7' (redirected from 'http://localhost:8080/api/v1/todo') from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
QUESTION: From this point I'm asking why Quarkus re-initiated authentication on first ajax request on granted resource, guess is that Quarkus does automatically the exchange of code for id & access tokens but doesn't persist the access token in cookies or any other way on client, do I understand correctly that handling of access token must be done explicitly after the exchange? I'm wondering that Quarkus has so many extensions and configurations but doesn't really help you with putting an access token into a cookie? Just making sure that I didn't miss anything there.
Here are the configuration and realm properties I used to enable the authentication
# application
quarkus.application.name=reactive-todos-service
# cors
quarkus.http.root-path=/api/v1
quarkus.http.cors=true
%dev.quarkus.http.cors.origins=/.*/
# web authentication (oidc)
%prod.quarkus.oidc.auth-server-url=https://localhost:8543/realms/quarkus
quarkus.oidc.client-id=reactive-todos-service
quarkus.oidc.credentials.secret=secret
quarkus.oidc.application-type=web_app
quarkus.oidc.roles.source=accesstoken
quarkus.oidc.token-state-manager.strategy=keep_all_tokens
quarkus.oidc.token-state-manager.split-tokens=true
quarkus.oidc.token-state-manager.encryption-secret=eUk1p7UB3nFiXZGUXi0uph1Y9p34YhBU
# web authorization
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
quarkus.http.auth.permission.public.paths=/api/v1/q/dev/*
quarkus.http.auth.permission.public.policy=permit
# keycloak
quarkus.keycloak.devservices.realm-path=reactive-todos-realm.json
EntryResource that I'm successfully getting after redirect from IdP
@Path("/")
@Produces(MediaType.TEXT_HTML)
public class EntryResource {
@Inject
@IdToken
JsonWebToken idToken;
@Location("v1/entry/authorized.qute.html")
Template authorizedTemplate;
@GET
@RolesAllowed({"user"})
public Uni<TemplateInstance> getAuthorized() {
return Uni.createFrom().item(authorizedTemplate.data("username", idToken.getClaim("preferred_username")));
}
}
pointing to @SergeyBeryozkin answer
the issue was indeed related to cookie age, I corrected the value in realm configuration file by setting ssoSessionMaxLifespan