Skip to content

Commit

Permalink
Support global properties for azure active directory (#25721)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rujun Chen authored Dec 3, 2021
1 parent 41baf77 commit afca541
Show file tree
Hide file tree
Showing 33 changed files with 449 additions and 353 deletions.
6 changes: 6 additions & 0 deletions sdk/spring/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
### Features Added

### Breaking Changes
1. Property name "spring.cloud.azure.active-directory.tenant-id" changed to "spring.cloud.azure.active-directory.profile.tenant-id".
2. Property name "spring.cloud.azure.active-directory.client-id" changed to "spring.cloud.azure.active-directory.credential.client-id".
3. Property name "spring.cloud.azure.active-directory.client-secret" changed to "spring.cloud.azure.active-directory.credential.client-secret".
4. Property name "spring.cloud.azure.active-directory.base-uri" changed to "spring.cloud.azure.active-directory.profile.environment.active-directory-endpoint".
5. Property name "spring.cloud.azure.active-directory.graph-base-uri" changed to "spring.cloud.azure.active-directory.profile.environment.microsoft-graph-endpoint".
5. Property name "spring.cloud.azure.active-directory.graph-membership-uri" changed to "spring.cloud.azure.active-directory.profile.environment.microsoft-graph-endpoint" and "spring.cloud.azure.active-directory.user-group.use-transitive-members".

### Bugs Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@


import com.azure.spring.cloud.autoconfigure.aad.implementation.oauth2.AADOAuth2ClientConfiguration;
import com.azure.spring.cloud.autoconfigure.aad.properties.AADAuthenticationProperties;
import com.azure.spring.cloud.autoconfigure.aad.properties.AADResourceServerProperties;
import com.azure.spring.cloud.autoconfigure.aad.properties.AADPropertiesConfiguration;
import com.azure.spring.cloud.autoconfigure.aad.webapi.AADResourceServerConfiguration;
import com.azure.spring.cloud.autoconfigure.aad.webapp.AADWebApplicationConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

Expand All @@ -20,11 +18,8 @@
*/
@Configuration
@ConditionalOnProperty(value = "spring.cloud.azure.active-directory.enabled", havingValue = "true")
@EnableConfigurationProperties({
AADAuthenticationProperties.class,
AADResourceServerProperties.class
})
@Import({
AADPropertiesConfiguration.class,
AADWebApplicationConfiguration.class,
AADResourceServerConfiguration.class,
AADOAuth2ClientConfiguration.class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ public AADAuthenticationFilter(AADAuthenticationProperties aadAuthenticationProp
UserPrincipalManager userPrincipalManager) {
this.userPrincipalManager = userPrincipalManager;
this.azureADGraphClient = new AzureADGraphClient(
aadAuthenticationProperties.getClientId(),
aadAuthenticationProperties.getClientSecret(),
aadAuthenticationProperties.getCredential().getClientId(),
aadAuthenticationProperties.getCredential().getClientSecret(),
aadAuthenticationProperties,
endpoints
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import com.azure.spring.cloud.autoconfigure.aad.core.AADAuthorizationServerEndpoints;
import com.azure.spring.cloud.autoconfigure.aad.properties.AADAuthenticationProperties;
import com.azure.spring.cloud.autoconfigure.aad.properties.AADPropertiesConfiguration;
import com.nimbusds.jose.jwk.source.DefaultJWKSetCache;
import com.nimbusds.jose.jwk.source.JWKSetCache;
import com.nimbusds.jose.util.DefaultResourceRetriever;
Expand All @@ -17,16 +18,16 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.concurrent.TimeUnit;

/**
* {@link EnableAutoConfiguration Auto-configuration} for Azure Active Authentication filters.
* <p>
* The configuration will not be activated if no {@literal spring.cloud.azure.active-directory.client-id} property provided.
* The configuration will not be activated if no {@literal spring.cloud.azure.active-directory.credential.client-id} property provided.
* <p>
* A stateless filter {@link AADAppRoleStatelessAuthenticationFilter} will be auto-configured by specifying {@literal
* spring.cloud.azure.active-directory.session-stateless=true}. Otherwise, {@link AADAuthenticationFilter} will be configured.
Expand All @@ -35,8 +36,8 @@
@ConditionalOnWebApplication
@ConditionalOnExpression("${spring.cloud.azure.active-directory.enabled:false}")
@ConditionalOnMissingClass({ "org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken" })
@ConditionalOnProperty(prefix = AADAuthenticationFilterAutoConfiguration.PROPERTY_PREFIX, value = { "client-id" })
@EnableConfigurationProperties({ AADAuthenticationProperties.class })
@ConditionalOnProperty(prefix = AADAuthenticationFilterAutoConfiguration.PROPERTY_PREFIX, value = { "credential.client-id" })
@Import(AADPropertiesConfiguration.class)
public class AADAuthenticationFilterAutoConfiguration {
/**
* The property prefix
Expand All @@ -55,7 +56,8 @@ public class AADAuthenticationFilterAutoConfiguration {
*/
public AADAuthenticationFilterAutoConfiguration(AADAuthenticationProperties properties) {
this.properties = properties;
this.endpoints = new AADAuthorizationServerEndpoints(properties.getBaseUri(), properties.getTenantId());
this.endpoints = new AADAuthorizationServerEndpoints(properties.getProfile().getEnvironment().getActiveDirectoryEndpoint(),
properties.getProfile().getTenantId());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public UserPrincipalManager(AADAuthorizationServerEndpoints endpoints,
this.explicitAudienceCheck = explicitAudienceCheck;
if (explicitAudienceCheck) {
// client-id for "normal" check
this.validAudiences.add(this.aadAuthenticationProperties.getClientId());
this.validAudiences.add(this.aadAuthenticationProperties.getCredential().getClientId());
// app id uri for client credentials flow (server to server communication)
this.validAudiences.add(this.aadAuthenticationProperties.getAppIdUri());
}
Expand Down Expand Up @@ -120,7 +120,7 @@ public UserPrincipalManager(AADAuthorizationServerEndpoints endpoints,
this.explicitAudienceCheck = explicitAudienceCheck;
if (explicitAudienceCheck) {
// client-id for "normal" check
this.validAudiences.add(this.aadAuthenticationProperties.getClientId());
this.validAudiences.add(this.aadAuthenticationProperties.getCredential().getClientId());
// app id uri for client credentials flow (server to server communication)
this.validAudiences.add(this.aadAuthenticationProperties.getAppIdUri());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;

import java.util.Optional;

Expand All @@ -34,10 +33,6 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM
message.notAvailable("AAD authorization properties(spring.cloud.azure.active-directory" + ".xxx)"));
}

if (!StringUtils.hasText(properties.getClientId())) {
return ConditionOutcome.noMatch(message.didNotFind("spring.cloud.azure.active-directory.client-id").atAll());
}

// Bind properties will not execute AADAuthenticationProperties#afterPropertiesSet()
AADApplicationType applicationType = Optional.ofNullable(properties.getApplicationType())
.orElseGet(AADApplicationType::inferApplicationTypeByDependencies);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;

import java.util.Optional;

Expand All @@ -34,10 +33,6 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM
return ConditionOutcome.noMatch(message.notAvailable("aad authorization properties"));
}

if (!StringUtils.hasText(properties.getClientId())) {
return ConditionOutcome.noMatch(message.didNotFind("client-id").atAll());
}

// Bind properties will not execute AADAuthenticationProperties#afterPropertiesSet()
AADApplicationType applicationType = Optional.ofNullable(properties.getApplicationType())
.orElseGet(AADApplicationType::inferApplicationTypeByDependencies);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public AADClientRegistrationRepository(AADAuthenticationProperties properties) {
// AAD server will return error if:
// 1. authorizationCodeScopes have more than one resource server.
// 2. accessTokenScopes have no resource server
String newScope = properties.getGraphBaseUri() + "User.Read";
String newScope = properties.getProfile().getEnvironment().getMicrosoftGraphEndpoint() + "User.Read";
accessTokenScopes.add(newScope);
authorizationCodeScopes.add(newScope);
}
Expand Down Expand Up @@ -120,10 +120,10 @@ private Set<String> azureClientAccessTokenScopes(AADAuthenticationProperties pro
// 2. https://github.com/Azure/azure-sdk-for-java/issues/21284#issuecomment-888725241
if (properties.allowedGroupNamesConfigured()) {
// "Directory.Read.All" allows to get group id and group name.
result.add(properties.getGraphBaseUri() + "Directory.Read.All");
result.add(properties.getProfile().getEnvironment().getMicrosoftGraphEndpoint() + "Directory.Read.All");
} else if (properties.allowedGroupIdsConfigured()) {
// "User.Read" allows to get group id, but not allow to get group name.
result.add(properties.getGraphBaseUri() + "User.Read");
// "User.Read" allows getting group id, but not allow getting group name.
result.add(properties.getProfile().getEnvironment().getMicrosoftGraphEndpoint() + "User.Read");
}
return result;
}
Expand All @@ -142,15 +142,15 @@ private ClientRegistration toClientRegistration(String registrationId,
Collection<String> scopes,
AADAuthenticationProperties properties) {
AADAuthorizationServerEndpoints endpoints =
new AADAuthorizationServerEndpoints(properties.getBaseUri(), properties.getTenantId());
new AADAuthorizationServerEndpoints(properties.getProfile().getEnvironment().getActiveDirectoryEndpoint(), properties.getProfile().getTenantId());
return ClientRegistration.withRegistrationId(registrationId)
.clientName(registrationId)
.authorizationGrantType(new AuthorizationGrantType((aadAuthorizationGrantType.getValue())))
.scope(scopes)
.redirectUri(properties.getRedirectUriTemplate())
.userNameAttributeName(properties.getUserNameAttribute())
.clientId(properties.getClientId())
.clientSecret(properties.getClientSecret())
.clientId(properties.getCredential().getClientId())
.clientSecret(properties.getCredential().getClientSecret())
.authorizationUri(endpoints.authorizationEndpoint())
.tokenUri(endpoints.tokenEndpoint())
.jwkSetUri(endpoints.jwkSetEndpoint())
Expand Down
Loading

0 comments on commit afca541

Please sign in to comment.