Closed oleksandr-manko closed 2 years ago
/cc @pedroigor, @sberyozkin
@oleksandr-manko thanks for not marking it as a bug :-).
Can you let me know please, what is returned with https://my-test.auth.eu-central-1.amazoncognito.com/.well-known/openid-configuration
? If the JWKS URI is different there to what you use, then can you clarify why you need to use different keys ?
thanks
Hi @sberyozkin!
https://my-test.auth.eu-central-1.amazoncognito.com/.well-known/openid-configuration
is a wring url:
The right one is https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX/.well-known/openid-configuration
The response was provided in the description above
@oleksandr-manko thanks, in that case it should just work if you set
quarkus.oidc.auth-server-url=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX
Have you tried it ?
@sberyozkin It work only if we work in service
mode (quarkus.oidc.application-type=service
) when we receive JWT token from outside and just validate the token and perform authorization based on the token. But If we want work in web-app
mode when we perform authentication (obtain the token inside the app) it doesn't work 'cause we need all the endpoints e.g. :
quarkus.oidc.application-type=web-app
quarkus.oidc.auth-server-url=https://my-test.auth.eu-central-1.amazoncognito.com
quarkus.oidc.authorization-path=/oauth2/authorize
quarkus.oidc.token-path=/oauth2/token
# ??? doesn't work ???
quarkus.oidc.jwks-path=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX/.well-known/jwks.json
quarkus.oidc.roles.source=accesstoken
quarkus.oidc.authentication.user-info-required=false
quarkus.oidc.roles.role-claim-path=scope
quarkus.oidc.authentication.scopes=test-api/read
quarkus.oidc.client-id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
quarkus.oidc.credentials.secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
So for all the endpoints I need a single domain except JWKS endpoint. For JWKS I need a different domain
@oleksandr-manko I'm sorry, I don't understand why it does not work.
As documented here one should only disable the discovery and set individual (relative) endpoint paths if the discovery does not work.
But in your case it does work - https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX
returns the authorization, jwks and token endpoint URLs, which quarkus-oidc
will use.
quarkus.oidc.auth-server-url
should point to the base URL which will return a discovery doc and it does not look like the one you set supports it.
I think your configuration should look like this:
quarkus.oidc.application-type=web-app
quarkus.oidc.auth-server-url=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX
quarkus.oidc.roles.source=accesstoken
quarkus.oidc.authentication.user-info-required=false
quarkus.oidc.roles.role-claim-path=scope
quarkus.oidc.authentication.scopes=test-api/read
quarkus.oidc.client-id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
quarkus.oidc.credentials.secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
That should work, I've seen users confirming quarkus-oidc
works with Cognito, it does not really matter what these individual URLs returned in the discovery doc point to.
Can you try please with the proposed config ?
@sberyozkin, no because authorization-path
and token-path
paths are on https://my-test.auth.eu-central-1.amazoncognito.com
domain and jwks-path
path is on https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX/
domain
2 endpoints are on one domain and 1 is on another one. But implementation considers all of them should be on the same domain. In case of AWS Cognito it doesn't work:
https://my-test.auth.eu-central-1.amazoncognito.com/oauth2/authorize
(domain 1)https://my-test.auth.eu-central-1.amazoncognito.com/oauth2/token
(domain 1)https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX/.well-known/jwks.json
(DOMAIN 2)@oleksandr-manko I must be slow today on Friday, sorry :-). Why do you say the implementation enforces it must be the same domain ?
What is the error you are getting ? Do you see the code which enforces it ?
AFAIK quarkus-oidc
would use discovered URLs directly.
If it does then it is a bug but which I'd consider not related to the calculation of the actual URLs (linked to in the issue description) - as it only runs when the auto-discovery is disabled.
Thanks
@oleksandr-manko
quarkus.oidc.auth-server-url=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX
will return all those endpoint URLs you have shown in your discovery doc above - and Quarkus will just use them - I don't see why it would not - so please help with more clarifications
Note I'll review the possibility of supporting all the endpoint URLs being the absolute ones when the auto-discovery is disabled - I recall looking into it - but for now I'd expect it to work without users having to be concerned about finding the JWKs URLs and other individual endpoint URLs
@sberyozkin Error the following
2021-09-10 17:02:50,753 ERROR [io.qua.run.Application] (Quarkus Main Thread) Failed to start application (with profile dev): io.quarkus.oidc.common.runtime.OidcEndpointAccessException
at io.quarkus.oidc.runtime.OidcProviderClient.getJsonWebKeySet(OidcProviderClient.java:76)
at io.quarkus.oidc.runtime.OidcProviderClient.lambda$getJsonWebKeySet$0(OidcProviderClient.java:55)
at io.smallrye.context.impl.wrappers.SlowContextualFunction.apply(SlowContextualFunction.java:21)
at io.smallrye.mutiny.operators.uni.UniOnItemTransform$UniOnItemTransformProcessor.onItem(UniOnItemTransform.java:36)
at io.smallrye.mutiny.vertx.AsyncResultUni.lambda$subscribe$1(AsyncResultUni.java:35)
at io.vertx.mutiny.ext.web.client.HttpRequest$10.handle(HttpRequest.java:717)
at io.vertx.mutiny.ext.web.client.HttpRequest$10.handle(HttpRequest.java:714)
at io.vertx.ext.web.client.impl.HttpContext.handleDispatchResponse(HttpContext.java:371)
at io.vertx.ext.web.client.impl.HttpContext.execute(HttpContext.java:358)
at io.vertx.ext.web.client.impl.HttpContext.next(HttpContext.java:336)
at io.vertx.ext.web.client.impl.HttpContext.fire(HttpContext.java:303)
at io.vertx.ext.web.client.impl.HttpContext.dispatchResponse(HttpContext.java:265)
at io.vertx.ext.web.client.impl.HttpContext.lambda$null$8(HttpContext.java:520)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:96)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:59)
at io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:37)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)
place in the extension: https://github.com/quarkusio/quarkus/blob/c317c45d3ee47b9ec66ae01188f07ddc877fb151/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java#L271
@oleksandr-manko
OK, so in your comment above you have confirmed that https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX
returns a metadata doc which contains an absolute
jwksURL.
And therefore I'm saying to you that if you set
quarkus.oidc,auth-server-url=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX
then the error above would not happen because https://github.com/quarkusio/quarkus/blob/c317c45d3ee47b9ec66ae01188f07ddc877fb151/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcRecorder.java#L271 will not be even executed.
@sberyozkin thanks it works. But how did it figure out endpoints? Ok got it It found endpoints here
} else {
final long connectionDelayInMillisecs = OidcCommonUtils.getConnectionDelayInMillis(oidcConfig);
metadataUni = OidcCommonUtils.discoverMetadata(client, authServerUriString, connectionDelayInMillisecs)
.onItem().transform(json -> new OidcConfigurationMetadata(json));
}
public static Uni<JsonObject> discoverMetadata(WebClient client, String authServerUrl, long connectionDelayInMillisecs) {
String discoveryUrl = authServerUrl + "/.well-known/openid-configuration";
return client.getAbs(discoveryUrl).send().onItem().transform((resp) -> {
if (resp.statusCode() == 200) {
return resp.bodyAsJsonObject();
} else {
LOG.tracef("Discovery has failed, status code: %d", resp.statusCode());
throw new OidcEndpointAccessException(resp.statusCode());
}
}).onFailure(oidcEndpointNotAvailable()).retry().withBackOff(CONNECTION_BACKOFF_DURATION, CONNECTION_BACKOFF_DURATION).expireIn(connectionDelayInMillisecs).onFailure().transform((t) -> {
return t.getCause();
});
}
In other words if quarkus.oidc.discovery-enabled=false
quarkus-oidc retrieves all the endpoints from quarkus.oidc.auth-server-url + "/.well-known/openid-configuration"
.
So in case of Cognito we should specify https://cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>
(e.g. https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_t12NbxXXX
) as quarkus.oidc.auth-server-url
Thanks you @sberyozkin!
@oleksandr-manko Np at all, glad it worked, nonetheless, as I said, I'll just take care of supporting the absolute URLs when the auto-discovery is disabled - it should also just work :-).
Let me re-open this issue and rename it so that the enhancement request is tracked
Description
tried to use quarkus-oidc with AWS Cognito and It doesn't work 'cause quarkus-oidc assumes that JWKS endpoint ALWAYS should have the same domain as the authorization server has. It's not always true. For instance, AWS Cognito has different domains for authorization servers and JWKS. In our case We have the following OIDC Configuration in Cognito:
We have
https://cognito-idp.eu-central-1.amazonaws.com
domain for JWKS andhttps://my-test.auth.eu-central-1.amazoncognito.com
as auth-server.We can only specify
quarkus.oidc.auth-server-url
andquarkus.oidc.jwks-path
. JWKS uri is a result of concatenation ofauth-server-url
andjwks-path
.It happens in
io.quarkus.oidc.runtime.OidcRecorder#createOidcClientUni(OidcTenantConfig, TlsConfig, Vertx)
line 271.Implementation ideas
Should be an ability to specify a full URI to JWKS including domain name in properties.