From d1de3985461e2a0bb9ad99f548bf35d79d55bc55 Mon Sep 17 00:00:00 2001 From: "florian.posch@beyondnow.com" Date: Thu, 8 Feb 2024 13:17:57 +0100 Subject: [PATCH] OAuth2 Auth provider incorrectly validating Access Tokens --- .../oauth2/impl/OAuth2AuthProviderImpl.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/vertx-auth-oauth2/src/main/java/io/vertx/ext/auth/oauth2/impl/OAuth2AuthProviderImpl.java b/vertx-auth-oauth2/src/main/java/io/vertx/ext/auth/oauth2/impl/OAuth2AuthProviderImpl.java index 4fb424805..b6b9496bd 100644 --- a/vertx-auth-oauth2/src/main/java/io/vertx/ext/auth/oauth2/impl/OAuth2AuthProviderImpl.java +++ b/vertx-auth-oauth2/src/main/java/io/vertx/ext/auth/oauth2/impl/OAuth2AuthProviderImpl.java @@ -32,13 +32,12 @@ import io.vertx.ext.auth.authentication.UsernamePasswordCredentials; import io.vertx.ext.auth.impl.jose.JWK; import io.vertx.ext.auth.impl.jose.JWT; -import io.vertx.ext.auth.oauth2.OAuth2Auth; -import io.vertx.ext.auth.oauth2.OAuth2FlowType; -import io.vertx.ext.auth.oauth2.OAuth2Options; -import io.vertx.ext.auth.oauth2.Oauth2Credentials; -import io.vertx.ext.auth.oauth2.OAuth2AuthorizationURL; +import io.vertx.ext.auth.oauth2.*; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import static java.lang.Math.max; @@ -673,22 +672,22 @@ private JsonObject validToken(JsonObject token, boolean idToken) throws IllegalS } } - if (target != null && target.size() > 0) { - if (idToken || jwtOptions.getAudience() == null) { - // https://openid.net/specs/openid-connect-core-1_0.html# $3.1.3.7. - // The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer - // identified by the iss (issuer) Claim as an audience. The aud (audience) Claim MAY contain an array with more - // than one element. The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, - // or if it contains additional audiences not trusted by the Client. - if (!target.contains(config.getClientId())) { - throw new IllegalStateException("Invalid JWT audience. expected: " + config.getClientId()); - } - } else { - final List aud = jwtOptions.getAudience(); - for (String el : aud) { - if (!target.contains(el)) { - throw new IllegalStateException("Invalid JWT audience. expected: " + el); - } + if (idToken && target != null && !target.isEmpty()) { + if (!target.contains(config.getClientId())) { + throw new IllegalStateException("Invalid JWT audience. expected: " + config.getClientId()); + } + if (!target.isEmpty()) { + List trustedAudiences = new ArrayList<>(); + Optional.ofNullable(jwtOptions.getAudience()) + .ifPresent(trustedAudiences::addAll); + trustedAudiences.add(config.getClientId()); + List untrustedAudiences = target.stream() + .filter(String.class::isInstance) + .map(String.class::cast) + .filter(additionalTarget -> !trustedAudiences.contains(additionalTarget)) + .collect(Collectors.toList()); + if (!untrustedAudiences.isEmpty()) { + throw new IllegalStateException("Invalid JWT audience. untrusted values: " + String.join(",", untrustedAudiences)); } } }