Closed as not planned
Closed as not planned
Description
Before reporting an issue
- I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
token-exchange
Describe the bug
The commit aeb1951 changed the loading of identity providers by introducing DefaultTokenExchangeProvider
::locateExchangeExternalTokenByAlias
.
Before Keycloak 26 it was possible to omit the subject_issuer
in an external token exchange, with Keycloak 26 this now results in a NPE because the issuer cannot be loaded.
Version
26.0.5
Regression
- The issue is a regression
Expected behavior
Either the token exchange works, or there is an error message returned such as Unauthorised?
Actual behavior
A NPE is thrown and the server returns:
{
"error": "unknown_error",
"error_description": "For more on this error consult the server log."
}
How to Reproduce?
Trigger an external token to internal token exchange using a permitted client for this token exchange, an external IDP and a valid access token issued by that external IDP.
POST http://localhost:8080/realms/master/protocol/openid-connect/token
Content-type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&client_id=<client id>
&subject_token=<valid jwt>
&subject_token_type=urn:ietf:params:oauth:token-type:jwt
&audience=<client id>
Anything else?
keycloak-1 | 2024-11-12 13:51:40,824 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-2) Uncaught server error: java.lang.NullPointerException: Cannot invoke "org.keycloak.models.IdentityProviderModel.getProviderId()" because "model" is null
keycloak-1 | at org.keycloak.services.resources.IdentityBrokerService.lambda$getIdentityProviderFactory$4(IdentityBrokerService.java:1334)
keycloak-1 | at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
keycloak-1 | at java.base/java.util.HashMap$ValueSpliterator.tryAdvance(HashMap.java:1808)
keycloak-1 | at java.base/java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:720)
keycloak-1 | at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
keycloak-1 | at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
keycloak-1 | at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
keycloak-1 | at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
keycloak-1 | at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
keycloak-1 | at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
keycloak-1 | at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
keycloak-1 | at org.keycloak.services.resources.IdentityBrokerService.getIdentityProviderFactory(IdentityBrokerService.java:1336)
keycloak-1 | at org.keycloak.protocol.oidc.DefaultTokenExchangeProvider.locateExchangeExternalTokenByAlias(DefaultTokenExchangeProvider.java:699)
keycloak-1 | at org.keycloak.protocol.oidc.DefaultTokenExchangeProvider.exchangeExternalToken(DefaultTokenExchangeProvider.java:521)
keycloak-1 | at org.keycloak.protocol.oidc.DefaultTokenExchangeProvider.tokenExchange(DefaultTokenExchangeProvider.java:164)
keycloak-1 | at org.keycloak.protocol.oidc.DefaultTokenExchangeProvider.exchange(DefaultTokenExchangeProvider.java:130)
keycloak-1 | at org.keycloak.protocol.oidc.grants.TokenExchangeGrantType.process(TokenExchangeGrantType.java:62)
keycloak-1 | at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.processGrantRequest(TokenEndpoint.java:151)
keycloak-1 | at org.keycloak.protocol.oidc.endpoints.TokenEndpoint$quarkusrestinvoker$processGrantRequest_6408e15340992839b66447750c221d9aaa837bd7.invoke(Unknown Source)
keycloak-1 | at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
keycloak-1 | at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
keycloak-1 | at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
keycloak-1 | at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:635)
keycloak-1 | at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
keycloak-1 | at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
keycloak-1 | at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
keycloak-1 | at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
keycloak-1 | at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
keycloak-1 | at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
keycloak-1 | at java.base/java.lang.Thread.run(Thread.java:1583)