Skip to content

Commit

Permalink
Merge pull request quarkusio#35005 from sberyozkin/fix_token_verifica…
Browse files Browse the repository at this point in the history
…tion_failure_message

Fix OIDC token verification failure message
  • Loading branch information
sberyozkin committed Jul 25, 2023
2 parents 599879b + 9579485 commit 919ba3d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,12 @@ private Uni<TokenVerificationResult> verifyTokenUni(TenantConfigContext resolved
}
}
LOG.debug("Starting the opaque token introspection");
return introspectTokenUni(resolvedContext, token);
return introspectTokenUni(resolvedContext, token, false);
} else if (resolvedContext.provider.getMetadata().getJsonWebKeySetUri() == null
|| resolvedContext.oidcConfig.token.requireJwtIntrospectionOnly) {
// Verify JWT token with the remote introspection
LOG.debug("Starting the JWT token introspection");
return introspectTokenUni(resolvedContext, token);
return introspectTokenUni(resolvedContext, token, false);
} else {
// Verify JWT token with the local JWK keys with a possible remote introspection fallback
try {
Expand Down Expand Up @@ -458,32 +458,47 @@ private Uni<TokenVerificationResult> verifySelfSignedTokenUni(TenantConfigContex
private Uni<TokenVerificationResult> refreshJwksAndVerifyTokenUni(TenantConfigContext resolvedContext, String token,
boolean enforceAudienceVerification) {
return resolvedContext.provider.refreshJwksAndVerifyJwtToken(token, enforceAudienceVerification)
.onFailure(f -> f.getCause() instanceof UnresolvableKeyException
&& resolvedContext.oidcConfig.token.allowJwtIntrospection)
.recoverWithUni(f -> introspectTokenUni(resolvedContext, token));
.onFailure(f -> fallbackToIntrospectionIfNoMatchingKey(f, resolvedContext))
.recoverWithUni(f -> introspectTokenUni(resolvedContext, token, true));
}

private Uni<TokenVerificationResult> introspectTokenUni(TenantConfigContext resolvedContext, final String token) {
private static boolean fallbackToIntrospectionIfNoMatchingKey(Throwable f, TenantConfigContext resolvedContext) {
if (!(f.getCause() instanceof UnresolvableKeyException)) {
LOG.debug("Local JWT token verification has failed, skipping the token introspection");
return false;
} else if (!resolvedContext.oidcConfig.token.allowJwtIntrospection) {
LOG.debug("JWT token does not have a matching verification key but JWT token introspection is disabled");
return false;
} else {
LOG.debug("Local JWT token verification has failed, attempting the token introspection");
return true;
}

}

private Uni<TokenVerificationResult> introspectTokenUni(TenantConfigContext resolvedContext, final String token,
boolean fallbackFromJwkMatch) {
TokenIntrospectionCache tokenIntrospectionCache = tenantResolver.getTokenIntrospectionCache();
Uni<TokenIntrospection> tokenIntrospectionUni = tokenIntrospectionCache == null ? null
: tokenIntrospectionCache
.getIntrospection(token, resolvedContext.oidcConfig, getIntrospectionRequestContext);
if (tokenIntrospectionUni == null) {
tokenIntrospectionUni = newTokenIntrospectionUni(resolvedContext, token);
tokenIntrospectionUni = newTokenIntrospectionUni(resolvedContext, token, fallbackFromJwkMatch);
} else {
tokenIntrospectionUni = tokenIntrospectionUni.onItem().ifNull()
.switchTo(new Supplier<Uni<? extends TokenIntrospection>>() {
@Override
public Uni<TokenIntrospection> get() {
return newTokenIntrospectionUni(resolvedContext, token);
return newTokenIntrospectionUni(resolvedContext, token, fallbackFromJwkMatch);
}
});
}
return tokenIntrospectionUni.onItem().transform(t -> new TokenVerificationResult(null, t));
}

private Uni<TokenIntrospection> newTokenIntrospectionUni(TenantConfigContext resolvedContext, String token) {
Uni<TokenIntrospection> tokenIntrospectionUni = resolvedContext.provider.introspectToken(token);
private Uni<TokenIntrospection> newTokenIntrospectionUni(TenantConfigContext resolvedContext, String token,
boolean fallbackFromJwkMatch) {
Uni<TokenIntrospection> tokenIntrospectionUni = resolvedContext.provider.introspectToken(token, fallbackFromJwkMatch);
if (tenantResolver.getTokenIntrospectionCache() == null || !resolvedContext.oidcConfig.allowTokenIntrospectionCache) {
return tokenIntrospectionUni;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,15 @@ public Uni<? extends TokenVerificationResult> apply(Void v) {
});
}

public Uni<TokenIntrospection> introspectToken(String token) {
public Uni<TokenIntrospection> introspectToken(String token, boolean fallbackFromJwkMatch) {
if (client.getMetadata().getIntrospectionUri() == null) {
LOG.debugf(
"Token issued to client %s can not be introspected because the introspection endpoint address is unknown - "
+ "please check if your OpenId Connect Provider supports the token introspection",
String errorMessage = String.format("Token issued to client %s "
+ (fallbackFromJwkMatch ? "does not have a matching verification key and it " : "")
+ "can not be introspected because the introspection endpoint address is unknown - "
+ "please check if your OpenId Connect Provider supports the token introspection",
oidcConfig.clientId.get());
throw new AuthenticationFailedException();

throw new AuthenticationFailedException(errorMessage);
}
return client.introspectToken(token).onItemOrFailure()
.transform(new BiFunction<TokenIntrospection, Throwable, TokenIntrospection>() {
Expand Down

0 comments on commit 919ba3d

Please sign in to comment.