diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerProperties.java index 196afbdc75fe..fd7ceba3c338 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,13 @@ public class OAuth2AuthorizationServerProperties implements InitializingBean { */ private String issuer; + /** + * Whether multiple issuers are allowed per host. Using path components in the URL of + * the issuer identifier enables supporting multiple issuers per host in a + * multi-tenant hosting configuration. + */ + private boolean multipleIssuersAllowed = false; + /** * Registered clients of the Authorization Server. */ @@ -52,6 +59,14 @@ public class OAuth2AuthorizationServerProperties implements InitializingBean { */ private final Endpoint endpoint = new Endpoint(); + public boolean isMultipleIssuersAllowed() { + return this.multipleIssuersAllowed; + } + + public void setMultipleIssuersAllowed(boolean multipleIssuersAllowed) { + this.multipleIssuersAllowed = multipleIssuersAllowed; + } + public String getIssuer() { return this.issuer; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapper.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapper.java index e53d587e192c..58083756c537 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapper.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,7 @@ AuthorizationServerSettings asAuthorizationServerSettings() { OAuth2AuthorizationServerProperties.OidcEndpoint oidc = endpoint.getOidc(); AuthorizationServerSettings.Builder builder = AuthorizationServerSettings.builder(); map.from(this.properties::getIssuer).to(builder::issuer); + map.from(this.properties::isMultipleIssuersAllowed).to(builder::multipleIssuersAllowed); map.from(endpoint::getAuthorizationUri).to(builder::authorizationEndpoint); map.from(endpoint::getDeviceAuthorizationUri).to(builder::deviceAuthorizationEndpoint); map.from(endpoint::getDeviceVerificationUri).to(builder::deviceVerificationEndpoint); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java index 8fbfb1eb4f2f..5773df36336b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerPropertiesMapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -113,6 +113,37 @@ void getAuthorizationServerSettingsWhenValidParametersShouldAdapt() { oidc.setUserInfoUri("/user"); AuthorizationServerSettings settings = this.mapper.asAuthorizationServerSettings(); assertThat(settings.getIssuer()).isEqualTo("https://example.com"); + assertThat(settings.isMultipleIssuersAllowed()).isFalse(); + assertThat(settings.getAuthorizationEndpoint()).isEqualTo("/authorize"); + assertThat(settings.getDeviceAuthorizationEndpoint()).isEqualTo("/device_authorization"); + assertThat(settings.getDeviceVerificationEndpoint()).isEqualTo("/device_verification"); + assertThat(settings.getTokenEndpoint()).isEqualTo("/token"); + assertThat(settings.getJwkSetEndpoint()).isEqualTo("/jwks"); + assertThat(settings.getTokenRevocationEndpoint()).isEqualTo("/revoke"); + assertThat(settings.getTokenIntrospectionEndpoint()).isEqualTo("/introspect"); + assertThat(settings.getOidcLogoutEndpoint()).isEqualTo("/logout"); + assertThat(settings.getOidcClientRegistrationEndpoint()).isEqualTo("/register"); + assertThat(settings.getOidcUserInfoEndpoint()).isEqualTo("/user"); + } + + @Test + void getAuthorizationServerSettingsWhenMultipleIssuersAllowedShouldAdapt() { + this.properties.setMultipleIssuersAllowed(true); + OAuth2AuthorizationServerProperties.Endpoint endpoints = this.properties.getEndpoint(); + endpoints.setAuthorizationUri("/authorize"); + endpoints.setDeviceAuthorizationUri("/device_authorization"); + endpoints.setDeviceVerificationUri("/device_verification"); + endpoints.setTokenUri("/token"); + endpoints.setJwkSetUri("/jwks"); + endpoints.setTokenRevocationUri("/revoke"); + endpoints.setTokenIntrospectionUri("/introspect"); + OAuth2AuthorizationServerProperties.OidcEndpoint oidc = endpoints.getOidc(); + oidc.setLogoutUri("/logout"); + oidc.setClientRegistrationUri("/register"); + oidc.setUserInfoUri("/user"); + AuthorizationServerSettings settings = this.mapper.asAuthorizationServerSettings(); + assertThat(settings.getIssuer()).isNull(); + assertThat(settings.isMultipleIssuersAllowed()).isTrue(); assertThat(settings.getAuthorizationEndpoint()).isEqualTo("/authorize"); assertThat(settings.getDeviceAuthorizationEndpoint()).isEqualTo("/device_authorization"); assertThat(settings.getDeviceVerificationEndpoint()).isEqualTo("/device_verification");