Skip to content

Commit 7eb0427

Browse files
author
Rujun Chen
authored
User Oauth2 WebClient instead of msal to get groups from graph. (Azure#17529)
* User Oauth2 WebClient instead of msal to get groups from graph.
1 parent db7a82d commit 7eb0427

File tree

46 files changed

+906
-558
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+906
-558
lines changed

eng/versioning/external_dependencies.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ org.springframework.boot:spring-boot-starter-logging;2.3.5.RELEASE
9999
org.springframework.boot:spring-boot-starter-test;2.3.5.RELEASE
100100
org.springframework.boot:spring-boot-starter-validation;2.3.5.RELEASE
101101
org.springframework.boot:spring-boot-starter-web;2.3.5.RELEASE
102+
org.springframework.boot:spring-boot-starter-webflux;2.3.5.RELEASE
102103
org.springframework.boot:spring-boot-starter;2.3.5.RELEASE
103104
org.springframework.boot:spring-boot;2.3.5.RELEASE
104105
org.springframework.data:spring-data-commons;2.3.5.RELEASE

sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-active-directory-backend-v2/src/main/java/com/azure/spring/sample/aad/security/AADOAuth2LoginSecurityConfig.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
package com.azure.spring.sample.aad.security;
55

6-
import com.azure.spring.autoconfigure.aad.AADAuthenticationFailureHandler;
76
import com.azure.spring.autoconfigure.aad.AADOAuth2AuthorizationRequestResolver;
8-
97
import org.springframework.beans.factory.annotation.Autowired;
108
import org.springframework.context.ApplicationContext;
119
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
@@ -31,16 +29,15 @@ protected void configure(HttpSecurity http) throws Exception {
3129
final ClientRegistrationRepository clientRegistrationRepository =
3230
applicationContext.getBean(ClientRegistrationRepository.class);
3331
http.authorizeRequests()
34-
.anyRequest().authenticated()
35-
.and()
36-
.oauth2Login()
37-
.userInfoEndpoint()
38-
.oidcUserService(oidcUserService)
39-
.and()
40-
.authorizationEndpoint()
41-
.authorizationRequestResolver(
42-
new AADOAuth2AuthorizationRequestResolver(clientRegistrationRepository))
43-
.and()
44-
.failureHandler(new AADAuthenticationFailureHandler());
32+
.anyRequest().authenticated()
33+
.and()
34+
.oauth2Login()
35+
.userInfoEndpoint()
36+
.oidcUserService(oidcUserService)
37+
.and()
38+
.authorizationEndpoint()
39+
.authorizationRequestResolver(
40+
new AADOAuth2AuthorizationRequestResolver(clientRegistrationRepository)
41+
);
4542
}
4643
}

sdk/spring/azure-spring-boot-starter-active-directory/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 3.0.0-beta.1 (Unreleased)
44
### Breaking Changes
5+
- Conditional access policy is not supported temporary, we may recover it in the future.
56
- Configuration items like `spring.security.oauth2.client.xxx` is not supported anymore. Please use the following configuration items instead:
67
```
78
azure.activedirectory.tenant-id=xxxxxx-your-tenant-id-xxxxxx

sdk/spring/azure-spring-boot-starter-active-directory/README.md

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -204,39 +204,6 @@ azure.activedirectory.environment=cn-v2-graph
204204
Please refer to [azure-spring-boot-sample-active-directory-backend-v2](https://github.com/Azure/azure-sdk-for-java/blob/master/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-active-directory-backend-v2/README.md) to see a sample configured to use the Microsoft Graph API.
205205

206206

207-
### AAD Conditional Access Policy
208-
Now azure-active-directory-spring-boot-starter has supported AAD conditional access policy, if you are using this policy, you need add **AADOAuth2AuthorizationRequestResolver** and **AADAuthenticationFailureHandler** to your WebSecurityConfigurerAdapter.
209-
<!-- embedme ../azure-spring-boot/src/samples/java/com/azure/spring/aad/AADOAuth2LoginConditionalPolicyConfigSample.java#L26-L53 -->
210-
```java
211-
@EnableWebSecurity
212-
@EnableGlobalMethodSecurity(prePostEnabled = true)
213-
public class AADOAuth2LoginConditionalPolicyConfigSample extends WebSecurityConfigurerAdapter {
214-
215-
@Autowired
216-
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
217-
218-
@Autowired
219-
ApplicationContext applicationContext;
220-
221-
@Override
222-
protected void configure(HttpSecurity http) throws Exception {
223-
final ClientRegistrationRepository clientRegistrationRepository =
224-
applicationContext.getBean(ClientRegistrationRepository.class);
225-
226-
http.authorizeRequests()
227-
.anyRequest().authenticated()
228-
.and()
229-
.oauth2Login()
230-
.userInfoEndpoint()
231-
.oidcUserService(oidcUserService)
232-
.and()
233-
.authorizationEndpoint()
234-
.authorizationRequestResolver(new AADOAuth2AuthorizationRequestResolver(clientRegistrationRepository))
235-
.and()
236-
.failureHandler(new AADAuthenticationFailureHandler());
237-
}
238-
}
239-
```
240207
### Customize scopes in authorize requests
241208

242209
By default, `azure-spring-boot-starter-active-directory` configures scopes of `openid`, `profile` and `https://graph.microsoft.com/user.read` to implement OpenID Connect protocol and access of Microsoft Graph API. For customization of scope, developers need to configure in the `application.properties`:

sdk/spring/azure-spring-boot-starter-active-directory/pom.xml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
<artifactId>spring-boot-starter-validation</artifactId>
3131
<version>2.3.5.RELEASE</version> <!-- {x-version-update;org.springframework.boot:spring-boot-starter-validation;external_dependency} -->
3232
</dependency>
33+
<dependency>
34+
<groupId>org.springframework.boot</groupId>
35+
<artifactId>spring-boot-starter-webflux</artifactId>
36+
<version>2.3.5.RELEASE</version> <!-- {x-version-update;org.springframework.boot:spring-boot-starter-webflux;external_dependency} -->
37+
</dependency>
3338
<dependency>
3439
<groupId>com.azure.spring</groupId>
3540
<artifactId>azure-spring-boot</artifactId>
@@ -70,6 +75,11 @@
7075
<artifactId>jackson-databind</artifactId>
7176
<version>2.11.3</version> <!-- {x-version-update;com.fasterxml.jackson.core:jackson-databind;external_dependency} -->
7277
</dependency>
78+
<dependency>
79+
<groupId>io.projectreactor.netty</groupId>
80+
<artifactId>reactor-netty</artifactId>
81+
<version>0.9.13.RELEASE</version> <!-- {x-version-update;io.projectreactor.netty:reactor-netty;external_dependency} -->
82+
</dependency>
7383
</dependencies>
7484

7585
<build>
@@ -85,12 +95,14 @@
8595
<include>com.fasterxml.jackson.core:jackson-databind:[2.11.3]</include> <!-- {x-include-update;com.fasterxml.jackson.core:jackson-databind;external_dependency} -->
8696
<include>com.microsoft.azure:msal4j:[1.8.0]</include> <!-- {x-include-update;com.microsoft.azure:msal4j;external_dependency} -->
8797
<include>com.nimbusds:nimbus-jose-jwt:[8.19]</include> <!-- {x-include-update;com.nimbusds:nimbus-jose-jwt;external_dependency} -->
88-
<include>org.springframework:spring-web:[5.2.10.RELEASE]</include> <!-- {x-include-update;org.springframework:spring-web;external_dependency} -->
89-
<include>org.springframework.boot:spring-boot-starter:[2.3.5.RELEASE]</include> <!-- {x-include-update;org.springframework.boot:spring-boot-starter;external_dependency} -->
98+
<include>io.projectreactor.netty:reactor-netty:[0.9.13.RELEASE]</include> <!-- {x-include-update;io.projectreactor.netty:reactor-netty;external_dependency} -->
9099
<include>org.springframework.boot:spring-boot-starter-validation:[2.3.5.RELEASE]</include> <!-- {x-include-update;org.springframework.boot:spring-boot-starter-validation;external_dependency} -->
100+
<include>org.springframework.boot:spring-boot-starter-webflux:[2.3.5.RELEASE]</include> <!-- {x-include-update;org.springframework.boot:spring-boot-starter-webflux;external_dependency} -->
101+
<include>org.springframework.boot:spring-boot-starter:[2.3.5.RELEASE]</include> <!-- {x-include-update;org.springframework.boot:spring-boot-starter;external_dependency} -->
91102
<include>org.springframework.security:spring-security-config:[5.3.5.RELEASE]</include> <!-- {x-include-update;org.springframework.security:spring-security-config;external_dependency} -->
92103
<include>org.springframework.security:spring-security-core:[5.3.5.RELEASE]</include> <!-- {x-include-update;org.springframework.security:spring-security-core;external_dependency} -->
93104
<include>org.springframework.security:spring-security-web:[5.3.5.RELEASE]</include> <!-- {x-include-update;org.springframework.security:spring-security-web;external_dependency} -->
105+
<include>org.springframework:spring-web:[5.2.10.RELEASE]</include> <!-- {x-include-update;org.springframework:spring-web;external_dependency} -->
94106
</includes>
95107
</bannedDependencies>
96108
</rules>

sdk/spring/azure-spring-boot-test-aad/src/test/java/com/azure/test/aad/auth/AppAutoConfigTest.java

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.azure.test.aad.auth;
22

3-
import com.azure.spring.aad.implementation.AzureClientRegistrationRepository;
4-
import com.azure.spring.aad.implementation.DefaultClient;
5-
import com.azure.spring.aad.implementation.IdentityEndpoints;
3+
import com.azure.spring.autoconfigure.aad.AuthorizationServerEndpoints;
4+
import com.azure.spring.autoconfigure.aad.AzureClientRegistrationRepository;
5+
import com.azure.spring.autoconfigure.aad.DefaultClient;
66
import com.azure.test.utils.AppRunner;
77
import org.junit.jupiter.api.Test;
88
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -34,17 +34,17 @@ public void clientRegistered() {
3434
assertEquals("fake-client-id", azureClientRegistration.getClientId());
3535
assertEquals("fake-client-secret", azureClientRegistration.getClientSecret());
3636

37-
IdentityEndpoints identityEndpoints = new IdentityEndpoints();
37+
AuthorizationServerEndpoints authorizationServerEndpoints = new AuthorizationServerEndpoints();
3838
assertEquals(
39-
identityEndpoints.authorizationEndpoint("fake-tenant-id"),
39+
authorizationServerEndpoints.authorizationEndpoint("fake-tenant-id"),
4040
azureClientRegistration.getProviderDetails().getAuthorizationUri()
4141
);
4242
assertEquals(
43-
identityEndpoints.tokenEndpoint("fake-tenant-id"),
43+
authorizationServerEndpoints.tokenEndpoint("fake-tenant-id"),
4444
azureClientRegistration.getProviderDetails().getTokenUri()
4545
);
4646
assertEquals(
47-
identityEndpoints.jwkSetEndpoint("fake-tenant-id"),
47+
authorizationServerEndpoints.jwkSetEndpoint("fake-tenant-id"),
4848
azureClientRegistration.getProviderDetails().getJwkSetUri()
4949
);
5050
assertEquals(
@@ -58,7 +58,10 @@ public void clientRegistered() {
5858
@Test
5959
public void clientRequiresPermissionRegistered() {
6060
try (AppRunner appRunner = createApp()) {
61-
appRunner.property("azure.activedirectory.authorization.graph.scope", "Calendars.Read");
61+
appRunner.property(
62+
"azure.activedirectory.authorization.graph.scope",
63+
"https://graph.microsoft.com/Calendars.Read"
64+
);
6265
appRunner.start();
6366

6467
ClientRegistrationRepository clientRegistrationRepository =
@@ -67,17 +70,23 @@ public void clientRequiresPermissionRegistered() {
6770
ClientRegistration graphClientRegistration = clientRegistrationRepository.findByRegistrationId("graph");
6871

6972
assertNotNull(azureClientRegistration);
70-
assertDefaultScopes(azureClientRegistration, "openid", "profile", "offline_access", "Calendars.Read");
73+
assertDefaultScopes(
74+
azureClientRegistration,
75+
"openid", "profile", "offline_access", "https://graph.microsoft.com/Calendars.Read"
76+
);
7177

7278
assertNotNull(graphClientRegistration);
73-
assertDefaultScopes(graphClientRegistration, "Calendars.Read");
79+
assertDefaultScopes(graphClientRegistration, "https://graph.microsoft.com/Calendars.Read");
7480
}
7581
}
7682

7783
@Test
7884
public void clientRequiresMultiPermissions() {
7985
try (AppRunner appRunner = createApp()) {
80-
appRunner.property("azure.activedirectory.authorization.graph.scope", "Calendars.Read");
86+
appRunner.property(
87+
"azure.activedirectory.authorization.graph.scope",
88+
"https://graph.microsoft.com/Calendars.Read"
89+
);
8190
appRunner.property(
8291
"azure.activedirectory.authorization.arm.scope",
8392
"https://management.core.windows.net/user_impersonation"
@@ -95,19 +104,22 @@ public void clientRequiresMultiPermissions() {
95104
"openid",
96105
"profile",
97106
"offline_access",
98-
"Calendars.Read",
107+
"https://graph.microsoft.com/Calendars.Read",
99108
"https://management.core.windows.net/user_impersonation"
100109
);
101110

102111
assertNotNull(graphClientRegistration);
103-
assertDefaultScopes(graphClientRegistration, "Calendars.Read");
112+
assertDefaultScopes(graphClientRegistration, "https://graph.microsoft.com/Calendars.Read");
104113
}
105114
}
106115

107116
@Test
108117
public void clientRequiresPermissionInDefaultClient() {
109118
try (AppRunner appRunner = createApp()) {
110-
appRunner.property("azure.activedirectory.authorization.azure.scope", "Calendars.Read");
119+
appRunner.property(
120+
"azure.activedirectory.authorization.azure.scope",
121+
"https://graph.microsoft.com/Calendars.Read"
122+
);
111123
appRunner.start();
112124

113125
ClientRegistrationRepository clientRegistrationRepository =
@@ -117,15 +129,18 @@ public void clientRequiresPermissionInDefaultClient() {
117129
assertNotNull(azureClientRegistration);
118130
assertDefaultScopes(
119131
azureClientRegistration,
120-
"openid", "profile", "offline_access", "Calendars.Read"
132+
"openid", "profile", "offline_access", "https://graph.microsoft.com/Calendars.Read"
121133
);
122134
}
123135
}
124136

125137
@Test
126138
public void aadAwareClientRepository() {
127139
try (AppRunner appRunner = createApp()) {
128-
appRunner.property("azure.activedirectory.authorization.graph.scope", "Calendars.Read");
140+
appRunner.property(
141+
"azure.activedirectory.authorization.graph.scope",
142+
"https://graph.microsoft.com/Calendars.Read")
143+
;
129144
appRunner.start();
130145

131146
AzureClientRegistrationRepository azureClientRegistrationRepository =
@@ -155,40 +170,44 @@ public void aadAwareClientRepository() {
155170
@Test
156171
public void defaultClientWithAuthzScope() {
157172
try (AppRunner appRunner = createApp()) {
158-
appRunner.property("azure.activedirectory.authorization.azure.scope", "Calendars.Read");
173+
appRunner.property(
174+
"azure.activedirectory.authorization.azure.scope",
175+
"https://graph.microsoft.com/Calendars.Read"
176+
);
159177
appRunner.start();
160178

161179
AzureClientRegistrationRepository azureClientRegistrationRepository =
162180
appRunner.getBean(AzureClientRegistrationRepository.class);
163181
assertDefaultScopes(
164182
azureClientRegistrationRepository.defaultClient(),
165-
"openid", "profile", "offline_access", "Calendars.Read"
183+
"openid", "profile", "offline_access", "https://graph.microsoft.com/Calendars.Read"
166184
);
167185
}
168186
}
169187

170188
@Test
171-
public void customizeUri() {
189+
public void customizeEnvironment() {
172190
try (AppRunner appRunner = createApp()) {
173-
appRunner.property("azure.activedirectory.uri", "http://localhost/");
191+
appRunner.property("azure.activedirectory.environment", "cn-v2-graph");
174192
appRunner.start();
175193

176194
AzureClientRegistrationRepository azureClientRegistrationRepository =
177195
appRunner.getBean(AzureClientRegistrationRepository.class);
178196
ClientRegistration azureClientRegistration =
179197
azureClientRegistrationRepository.findByRegistrationId("azure");
180198

181-
IdentityEndpoints endpoints = new IdentityEndpoints("http://localhost/");
199+
AuthorizationServerEndpoints authorizationServerEndpoints =
200+
new AuthorizationServerEndpoints("https://login.partner.microsoftonline.cn");
182201
assertEquals(
183-
endpoints.authorizationEndpoint("fake-tenant-id"),
202+
authorizationServerEndpoints.authorizationEndpoint("fake-tenant-id"),
184203
azureClientRegistration.getProviderDetails().getAuthorizationUri()
185204
);
186205
assertEquals(
187-
endpoints.tokenEndpoint("fake-tenant-id"),
206+
authorizationServerEndpoints.tokenEndpoint("fake-tenant-id"),
188207
azureClientRegistration.getProviderDetails().getTokenUri()
189208
);
190209
assertEquals(
191-
endpoints.jwkSetEndpoint("fake-tenant-id"),
210+
authorizationServerEndpoints.jwkSetEndpoint("fake-tenant-id"),
192211
azureClientRegistration.getProviderDetails().getJwkSetUri()
193212
);
194213
}

sdk/spring/azure-spring-boot-test-aad/src/test/java/com/azure/test/aad/auth/AuthorizedClientRepoTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.azure.test.aad.auth;
22

3-
import com.azure.spring.aad.implementation.AzureClientRegistrationRepository;
4-
import com.azure.spring.aad.implementation.AzureOAuth2AuthorizedClientRepository;
3+
import com.azure.spring.autoconfigure.aad.AzureClientRegistrationRepository;
4+
import com.azure.spring.autoconfigure.aad.AzureOAuth2AuthorizedClientRepository;
55
import com.azure.test.utils.AppRunner;
66
import org.junit.jupiter.api.AfterEach;
77
import org.junit.jupiter.api.BeforeEach;

sdk/spring/azure-spring-boot-test-aad/src/test/java/com/azure/test/aad/auth/AuthzCodeGrantRequestEntityConverterTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.azure.test.aad.auth;
22

3-
import com.azure.spring.aad.implementation.AzureClientRegistrationRepository;
4-
import com.azure.spring.aad.implementation.AzureOAuth2AuthorizationCodeGrantRequestEntityConverter;
3+
import com.azure.spring.autoconfigure.aad.AzureClientRegistrationRepository;
4+
import com.azure.spring.autoconfigure.aad.AzureOAuth2AuthorizationCodeGrantRequestEntityConverter;
55
import com.azure.test.utils.AppRunner;
66
import org.junit.jupiter.api.AfterEach;
77
import org.junit.jupiter.api.BeforeEach;

sdk/spring/azure-spring-boot/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 3.0.0-beta.1 (Unreleased)
44
### Breaking Changes
5+
- Conditional access policy is not supported temporary, we may recover it in the future.
56
- Configuration items like `spring.security.oauth2.client.xxx` is not supported anymore. Please use the following configuration items instead:
67
```
78
azure.activedirectory.tenant-id=xxxxxx-your-tenant-id-xxxxxx

0 commit comments

Comments
 (0)