Describe the bug
Currently Quarkus is including the full request path in the redirect URL. According to the OAuth 2.0 specification that OIDC is based on the redirect URL should be absolute.
Without a constant redirect path it is not possible to configure a single whitelisted login redirect URI in the OIDC IDP.
For example if http://localhost:5000/ is added to the IDP allowed redirect URLs if an unauthenticated user access http://localhost:5000/profile the redirect URL is sent as http://localhost:5000/profile which is not allowed in the IDP and the IDP displays an error.
Expected behavior
The redirect URL should have a static path like / or /oidc. The initially requested path should be stored in the web session or relayState and after the OAuth code authentication is performed the response should be redirected back to the initially requested path.
Actual behavior
Whatever unauthenticated request path that is submitted to Quarkus is set as the redirect URL. There are an infinite possible request path variations and it is not possible to include them all or configure wildcards in the IDP which would be a violation of the OAuth standard.
To Reproduce
Steps to reproduce the behavior:
Configuration
quarkus.oidc.auth-server-url=https://xxxxxxx.okta.com
quarkus.oidc.client-id=XXXXXXXXXXXXXXX
quarkus.oidc.credentials.secret=XXXXXXXXXXXXXXXXX
quarkus.oidc.authentication.scopes=openid,profile,groups
quarkus.oidc.application-type=web-app
quarkus.http.auth.permission.authenticated1.paths=/*
quarkus.http.auth.permission.authenticated1.policy=authenticated
quarkus.http.auth.permission.permit1.paths=/health/*
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET
/cc @sberyozkin @pedroigor @sebastienblanc
Hey Pedro @pedroigor lets talk about it when you get a chance. The 'state' cookie does not capture the request path
@aaronanderson
This address should be a Quarkus endpoint address. But of course it can be anything as far as the request URL is concerned, example, given /myendpoint there could be /myendpoint/1, /myendpoint/bar/foo so indeed the adapter needs to make sure that it is only /myendpoint segment which is added.
The problem is, the adapter sits in front of the JAX-RS chain, so it does not know what the @ApplicationPath value is.
So right now my thinking is we should have only the 1st path segment included, while the state cookie will keep whatever follows it, for example, given https://localhost:8080/myendpoint/1/2, the redirect URL will be https://localhost:8080/myendpoint and the state cookie will keep 1/2 and all the query parameters.
We can't avoid introducing a property because there could be some static resources on the URI path not overlapping with the JAX-RS path...
+1 to static OAuth/OIDC callback endpoint. However, bear in mind that there may be multiple tabs open to the application pointing to different URLs, so simply adding app URL to a cookie isn't sufficient. The state param can be used to include a pointer to which OIDC callback it is to pick up the correct URL on the callback.
@sberyozkin shall we have a property then? Would it be acceptable if we use this property to specify the redirect URI and fallback to current behavior if none is provided?
The approach we're using in the Keycloak adapters is not really a good approach. As mentioned here callback URL should really be a static OAuth/OIDC callback URL, not the regular app URLs.
Default behaviour should be a static URL, with perhaps different URLs for authorization code flow and RP initiated logout. Something like /oidc/login and /oidc/logout. It's probably rather unlikely that /oidc would clash with some of the apps own resources, but in case it does it could be nice to make it configurable.
@stianst @pedroigor Hi Stian, Pedro, I have a draft PR on the way (draft because I can't make Vertx reroute from the static redirect URL to the original one, will have to use a special Requires Stuart label :-) ), will CC you
Most helpful comment
The approach we're using in the Keycloak adapters is not really a good approach. As mentioned here callback URL should really be a static OAuth/OIDC callback URL, not the regular app URLs.
Default behaviour should be a static URL, with perhaps different URLs for authorization code flow and RP initiated logout. Something like /oidc/login and /oidc/logout. It's probably rather unlikely that /oidc would clash with some of the apps own resources, but in case it does it could be nice to make it configurable.