From 332d3361a5e5d13c14896537aac23901d6a81f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kraus?= Date: Wed, 7 Jun 2023 13:27:07 +0200 Subject: [PATCH] Issue #5860 - Make check for audience claim in access token optional in OIDC provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Kraus --- .../providers/oidc/common/BaseBuilder.java | 13 ++++++++++- .../providers/oidc/common/OidcConfig.java | 22 +++++++++++++++++++ .../common/OidcConfigFromBuilderTest.java | 12 ++++++++++ .../oidc/common/OidcConfigFromConfigTest.java | 18 +++++++++++++-- .../src/test/resources/application.yaml | 7 ++++++ 5 files changed, 69 insertions(+), 3 deletions(-) diff --git a/security/providers/oidc-common/src/main/java/io/helidon/security/providers/oidc/common/BaseBuilder.java b/security/providers/oidc-common/src/main/java/io/helidon/security/providers/oidc/common/BaseBuilder.java index 242ef6d685d..19f37d6e66b 100644 --- a/security/providers/oidc-common/src/main/java/io/helidon/security/providers/oidc/common/BaseBuilder.java +++ b/security/providers/oidc-common/src/main/java/io/helidon/security/providers/oidc/common/BaseBuilder.java @@ -65,6 +65,8 @@ abstract class BaseBuilder, T> implements BuilderForce https for redirects to identity provider. * This is helpful if you have a frontend SSL or cloud load balancer in front and Helidon is serving plain http. * + * + * {@code optional-audience} + * {@code false} + * Allow audience claim to be optional. + * * */ public final class OidcConfig extends TenantConfigImpl { @@ -363,6 +368,7 @@ public final class OidcConfig extends TenantConfigImpl { private final OidcCookieHandler tokenCookieHandler; private final OidcCookieHandler idTokenCookieHandler; private final OidcCookieHandler tenantCookieHandler; + private final boolean optionalAudience; private OidcConfig(Builder builder) { super(builder); @@ -393,6 +399,7 @@ private OidcConfig(Builder builder) { this.webClientBuilderSupplier = builder.webClientBuilderSupplier; this.defaultTenant = LazyValue.create(() -> Tenant.create(this, this)); + this.optionalAudience = builder.optionalAudience(); LOGGER.log(Level.TRACE, () -> "Redirect URI with host: " + frontendUri + redirectUri); } @@ -998,6 +1005,8 @@ public Builder config(Config config) { config.get("tenants").asList(Config.class) .ifPresent(confList -> confList.forEach(tenantConfig -> tenantFromConfig(config, tenantConfig))); + config.get("optional-audience").asBoolean().ifPresent(this::optionalAudience); + return this; } @@ -1528,5 +1537,18 @@ public Builder addTenantConfig(TenantConfig tenantConfig) { tenantConfigurations.put(tenantConfig.name(), tenantConfig); return this; } + + /** + * Allow audience claim to be optional. + * + * @param optional whether the audience claim is be optional (true) or not (false) + * @return updated builder instance + */ + @ConfiguredOption("false") + public Builder optionalAudience(Boolean optional) { + setOptionalAudience(optional); + return this; + } + } } diff --git a/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromBuilderTest.java b/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromBuilderTest.java index d1243e43153..c8b81580c96 100644 --- a/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromBuilderTest.java +++ b/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromBuilderTest.java @@ -193,6 +193,18 @@ void testCookieEncryptionPasswordFromBuilderConfig() { } } + @Test + void testOptionalAudience() { + OidcConfig config = OidcConfig.builder() + .identityUri(URI.create("http://localhost/identity")) + .clientSecret("top-secret") + .clientId("client-id") + .optionalAudience(true) + .build(); + String audience = config.audience(); + assertThat(audience, nullValue()); + } + // Stub the Builder class to be able to retrieve the cookie-encryption-password value private static class TestOidcConfigBuilder extends OidcConfig.Builder { diff --git a/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromConfigTest.java b/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromConfigTest.java index caef7d2425a..ba4a4c58fa7 100644 --- a/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromConfigTest.java +++ b/security/providers/oidc-common/src/test/java/io/helidon/security/providers/oidc/common/OidcConfigFromConfigTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021 Oracle and/or its affiliates. + * Copyright (c) 2018, 2023 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,20 @@ import io.helidon.config.Config; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + /** * Unit test for {@link OidcConfig}. */ class OidcConfigFromConfigTest extends OidcConfigAbstractTest { private OidcConfig oidcConfig; + private Config config; OidcConfigFromConfigTest() { - Config config = Config.builder() + config = Config.builder() .disableSystemPropertiesSource() .disableEnvironmentVariablesSource() .build(); @@ -37,4 +43,12 @@ class OidcConfigFromConfigTest extends OidcConfigAbstractTest { OidcConfig getConfig() { return oidcConfig; } + + @Test + void testOptionalAudience() { + OidcConfig oidcConfig = OidcConfig.create(config.get("security.oidc-optional-aud")); + String audience = oidcConfig.audience(); + assertThat(audience, nullValue()); + } + } diff --git a/security/providers/oidc-common/src/test/resources/application.yaml b/security/providers/oidc-common/src/test/resources/application.yaml index 231fc0ceaec..19941db5684 100644 --- a/security/providers/oidc-common/src/test/resources/application.yaml +++ b/security/providers/oidc-common/src/test/resources/application.yaml @@ -16,6 +16,7 @@ security: config.require-encryption: false + oidc-test: identity-uri: "https://identity.oracle.com" scope-audience: "https://something:7987/test-application" @@ -29,3 +30,9 @@ security: authorization-endpoint-uri: "https://identity.oracle.com/authorization" introspect-endpoint-uri: "https://identity.oracle.com/introspect" relative-uris: true + + oidc-optional-aud: + identity-uri: "https://my.identity" + client-id: "my-id" + client-secret: "my-well-known-secret" + optional-audience: true