Skip to content

Commit e1d96e7

Browse files
authored
1.10.0 release (#379)
1.10.0 release
1 parent 8bfcc3c commit e1d96e7

40 files changed

+875
-188
lines changed

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ The Microsoft Authentication Library for Java (MSAL4J) enables applications to i
88

99
Quick links:
1010

11-
| [Getting Started](https://docs.microsoft.com/azure/active-directory/develop/quickstart-v2-java-webapp) | [Docs](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki) | [Samples](https://aka.ms/aaddevsamplesv2) | [Support](README.md#community-help-and-support)
12-
| --- | --- | --- | --- |
11+
| [Getting Started](https://docs.microsoft.com/azure/active-directory/develop/quickstart-v2-java-webapp) | [Docs](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki) | [Samples](https://aka.ms/aaddevsamplesv2) | [Support](README.md#community-help-and-support) | [Feedback](https://forms.office.com/r/6AhHwQp3pe)
12+
| --- | --- | --- | --- | --- |
1313

1414
## Install
1515

1616
The library supports the following Java environments:
1717
- Java 8 (or higher)
1818

19-
Current version - 1.9.1
19+
Current version - 1.10.0
2020

2121
You can find the changes for each version in the [change log](https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/master/changelog.txt).
2222

@@ -28,13 +28,13 @@ Find [the latest package in the Maven repository](https://mvnrepository.com/arti
2828
<dependency>
2929
<groupId>com.microsoft.azure</groupId>
3030
<artifactId>msal4j</artifactId>
31-
<version>1.9.1</version>
31+
<version>1.10.0</version>
3232
</dependency>
3333
```
3434
### Gradle
3535

3636
```
37-
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.9.1'
37+
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.10.0'
3838
```
3939

4040
## Usage
@@ -68,6 +68,9 @@ We leverage [Stack Overflow](http://stackoverflow.com/) to work with the communi
6868

6969
We recommend you use the "msal" tag so we can see it! Here is the latest Q&A on Stack Overflow for MSAL: [http://stackoverflow.com/questions/tagged/msal](http://stackoverflow.com/questions/tagged/msal)
7070

71+
## Submit Feedback
72+
We'd like your thoughts on this library. Please complete [this short survey.](https://forms.office.com/r/6AhHwQp3pe)
73+
7174
## Security Reporting
7275

7376
If you find a security issue with our libraries or services please report it to [[email protected]](mailto:[email protected]) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](http://aka.ms/bugbounty) program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://technet.microsoft.com/security/dd252948) and subscribing to Security Advisory Alerts.

changelog.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
Version 1.10.0
2+
=============
3+
- Instance aware support for interactive requests
4+
- Default cache lookup for on-behalf-of and client credential flows
5+
- Cross cloud accounts support
6+
- Using default security provider for client certificate creation
7+
- Upgrades the commons-io dependency 2.6 -> 2.7
8+
- Upgrades the oauth2-oidc-sdk dependency 8.23.1 -> 9.4
9+
- Upgrades the guava dependency 26.0 -> 29.0
10+
111
Version 1.9.1
212
=============
313
- Update com.fasterxml.jackson.core.jackson-databind to 2.12.1

pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.microsoft.azure</groupId>
55
<artifactId>msal4j</artifactId>
6-
<version>1.9.1</version>
6+
<version>1.10.0</version>
77
<packaging>jar</packaging>
88
<name>msal4j</name>
99
<description>
@@ -36,7 +36,7 @@
3636
<dependency>
3737
<groupId>com.nimbusds</groupId>
3838
<artifactId>oauth2-oidc-sdk</artifactId>
39-
<version>8.23.1</version>
39+
<version>9.4</version>
4040
</dependency>
4141
<dependency>
4242
<groupId>org.slf4j</groupId>
@@ -113,7 +113,7 @@
113113
<dependency>
114114
<groupId>com.google.guava</groupId>
115115
<artifactId>guava</artifactId>
116-
<version>26.0-jre</version>
116+
<version>29.0-jre</version>
117117
<scope>test</scope>
118118
</dependency>
119119
<dependency>
@@ -125,7 +125,7 @@
125125
<dependency>
126126
<groupId>commons-io</groupId>
127127
<artifactId>commons-io</artifactId>
128-
<version>2.6</version>
128+
<version>2.7</version>
129129
<scope>test</scope>
130130
</dependency>
131131
</dependencies>

src/integrationtest/java/com.microsoft.aad.msal4j/AcquireTokenInteractiveIT.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
package com.microsoft.aad.msal4j;
55

6+
import labapi.AzureEnvironment;
67
import labapi.B2CProvider;
78
import labapi.FederationProvider;
89
import labapi.User;
@@ -75,6 +76,14 @@ public void acquireTokenWithAuthorizationCode_B2C_Local(String environment){
7576
assertAcquireTokenB2C(user);
7677
}
7778

79+
@Test
80+
public void acquireTokenInteractive_ManagedUser_InstanceAware(){
81+
cfg = new Config(AzureEnvironment.AZURE);
82+
83+
User user = labUserProvider.getDefaultUser(AzureEnvironment.AZURE_US_GOVERNMENT);
84+
assertAcquireTokenInstanceAware(user);
85+
}
86+
7887
private void assertAcquireTokenAAD(User user){
7988
PublicClientApplication pca;
8089
try {
@@ -134,6 +143,31 @@ private void assertAcquireTokenB2C(User user){
134143
Assert.assertNotNull(result.idToken());
135144
}
136145

146+
private void assertAcquireTokenInstanceAware(User user) {
147+
PublicClientApplication pca;
148+
try {
149+
pca = PublicClientApplication.builder(
150+
user.getAppId()).
151+
authority(cfg.organizationsAuthority()).
152+
build();
153+
} catch (MalformedURLException ex) {
154+
throw new RuntimeException(ex.getMessage());
155+
}
156+
157+
IAuthenticationResult result = acquireTokenInteractive_instanceAware(user, pca, cfg.graphDefaultScope());
158+
159+
Assert.assertNotNull(result);
160+
Assert.assertNotNull(result.accessToken());
161+
Assert.assertNotNull(result.idToken());
162+
Assert.assertEquals(user.getUpn(), result.account().username());
163+
164+
//This test is using a client app with the login.microsoftonline.com config to get tokens for a login.microsoftonline.us user,
165+
// so when using instance aware the result's environment will be for the user/account and not the client app
166+
Assert.assertNotEquals(pca.authenticationAuthority.host, result.environment());
167+
Assert.assertEquals(result.account().environment(), result.environment());
168+
Assert.assertEquals(result.account().environment(), pca.getAccounts().join().iterator().next().environment());
169+
}
170+
137171
private IAuthenticationResult acquireTokenInteractive(
138172
User user,
139173
PublicClientApplication pca,
@@ -164,6 +198,36 @@ private IAuthenticationResult acquireTokenInteractive(
164198
return result;
165199
}
166200

201+
private IAuthenticationResult acquireTokenInteractive_instanceAware(
202+
User user,
203+
PublicClientApplication pca,
204+
String scope){
205+
206+
IAuthenticationResult result;
207+
try {
208+
URI url = new URI("http://localhost:8080");
209+
210+
SystemBrowserOptions browserOptions =
211+
SystemBrowserOptions
212+
.builder()
213+
.openBrowserAction(new SeleniumOpenBrowserAction(user, pca))
214+
.build();
215+
216+
InteractiveRequestParameters parameters = InteractiveRequestParameters
217+
.builder(url)
218+
.scopes(Collections.singleton(scope))
219+
.systemBrowserOptions(browserOptions).instanceAware(true)
220+
.build();
221+
222+
result = pca.acquireToken(parameters).get();
223+
224+
} catch(Exception e){
225+
LOG.error("Error acquiring token with authCode: " + e.getMessage());
226+
throw new RuntimeException("Error acquiring token with authCode: " + e.getMessage());
227+
}
228+
return result;
229+
}
230+
167231
class SeleniumOpenBrowserAction implements OpenBrowserAction {
168232

169233
private User user;

src/integrationtest/java/com.microsoft.aad.msal4j/ClientCredentialsIT.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,45 @@ public void acquireTokenClientCredentials_ClientAssertion() throws Exception{
6060
assertAcquireTokenCommon(clientId, credential);
6161
}
6262

63+
@Test
64+
public void acquireTokenClientCredentials_DefaultCacheLookup() throws Exception{
65+
AppCredentialProvider appProvider = new AppCredentialProvider(AzureEnvironment.AZURE);
66+
final String clientId = appProvider.getLabVaultAppId();
67+
final String password = appProvider.getLabVaultPassword();
68+
IClientCredential credential = ClientCredentialFactory.createFromSecret(password);
69+
70+
ConfidentialClientApplication cca = ConfidentialClientApplication.builder(
71+
clientId, credential).
72+
authority(TestConstants.MICROSOFT_AUTHORITY).
73+
build();
74+
75+
IAuthenticationResult result1 = cca.acquireToken(ClientCredentialParameters
76+
.builder(Collections.singleton(KEYVAULT_DEFAULT_SCOPE))
77+
.build())
78+
.get();
79+
80+
Assert.assertNotNull(result1);
81+
Assert.assertNotNull(result1.accessToken());
82+
83+
IAuthenticationResult result2 = cca.acquireToken(ClientCredentialParameters
84+
.builder(Collections.singleton(KEYVAULT_DEFAULT_SCOPE))
85+
.build())
86+
.get();
87+
88+
Assert.assertEquals(result1.accessToken(), result2.accessToken());
89+
90+
IAuthenticationResult result3 = cca.acquireToken(ClientCredentialParameters
91+
.builder(Collections.singleton(KEYVAULT_DEFAULT_SCOPE))
92+
.skipCache(true)
93+
.build())
94+
.get();
95+
96+
Assert.assertNotNull(result3);
97+
Assert.assertNotNull(result3.accessToken());
98+
Assert.assertNotEquals(result2.accessToken(), result3.accessToken());
99+
}
100+
101+
63102
private void assertAcquireTokenCommon(String clientId, IClientCredential credential) throws Exception{
64103
ConfidentialClientApplication cca = ConfidentialClientApplication.builder(
65104
clientId, credential).

src/integrationtest/java/com.microsoft.aad.msal4j/OnBehalfOfIT.java

Lines changed: 103 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,36 @@
1111

1212
@Test
1313
public class OnBehalfOfIT {
14-
private String accessToken;
1514

1615
private Config cfg;
1716

18-
private void setUp() throws Exception{
19-
LabUserProvider labUserProvider = LabUserProvider.getInstance();
20-
User user = labUserProvider.getDefaultUser(cfg.azureEnvironment);
17+
@Test(dataProvider = "environments", dataProviderClass = EnvironmentsProvider.class)
18+
public void acquireTokenWithOBO_Managed(String environment) throws Exception {
19+
cfg = new Config(environment);
20+
String accessToken = this.getAccessToken();
2121

22-
String clientId = cfg.appProvider.getAppId();
23-
String apiReadScope = cfg.appProvider.getOboAppIdURI() + "/user_impersonation";
22+
final String clientId = cfg.appProvider.getOboAppId();
23+
final String password = cfg.appProvider.getOboAppPassword();
2424

25-
PublicClientApplication pca = PublicClientApplication.builder(
26-
clientId).
27-
authority(cfg.tenantSpecificAuthority()).
28-
build();
25+
ConfidentialClientApplication cca =
26+
ConfidentialClientApplication.builder(clientId, ClientCredentialFactory.createFromSecret(password)).
27+
authority(cfg.tenantSpecificAuthority()).
28+
build();
2929

30-
IAuthenticationResult result = pca.acquireToken(
31-
UserNamePasswordParameters.builder(Collections.singleton(apiReadScope),
32-
user.getUpn(),
33-
user.getPassword().toCharArray()).build()).get();
30+
IAuthenticationResult result =
31+
cca.acquireToken(OnBehalfOfParameters.builder(
32+
Collections.singleton(cfg.graphDefaultScope()),
33+
new UserAssertion(accessToken)).build()).
34+
get();
3435

35-
accessToken = result.accessToken();
36+
Assert.assertNotNull(result);
37+
Assert.assertNotNull(result.accessToken());
3638
}
3739

3840
@Test(dataProvider = "environments", dataProviderClass = EnvironmentsProvider.class)
39-
public void acquireTokenWithOBO_Managed(String environment) throws Exception {
41+
public void acquireTokenWithOBO_testCache(String environment) throws Exception {
4042
cfg = new Config(environment);
41-
42-
setUp();
43+
String accessToken = this.getAccessToken();
4344

4445
final String clientId = cfg.appProvider.getOboAppId();
4546
final String password = cfg.appProvider.getOboAppPassword();
@@ -49,14 +50,94 @@ public void acquireTokenWithOBO_Managed(String environment) throws Exception {
4950
authority(cfg.tenantSpecificAuthority()).
5051
build();
5152

52-
IAuthenticationResult result =
53+
IAuthenticationResult result1 =
54+
cca.acquireToken(OnBehalfOfParameters.builder(
55+
Collections.singleton(TestConstants.USER_READ_SCOPE),
56+
new UserAssertion(accessToken)).build()).
57+
get();
58+
59+
Assert.assertNotNull(result1);
60+
Assert.assertNotNull(result1.accessToken());
61+
62+
// Same scope and userAssertion, should return cached tokens
63+
IAuthenticationResult result2 =
64+
cca.acquireToken(OnBehalfOfParameters.builder(
65+
Collections.singleton(TestConstants.USER_READ_SCOPE),
66+
new UserAssertion(accessToken)).build()).
67+
get();
68+
69+
Assert.assertEquals(result1.accessToken(), result2.accessToken());
70+
71+
// Scope 2, should return new token
72+
IAuthenticationResult result3 =
5373
cca.acquireToken(OnBehalfOfParameters.builder(
5474
Collections.singleton(cfg.graphDefaultScope()),
5575
new UserAssertion(accessToken)).build()).
5676
get();
5777

58-
Assert.assertNotNull(result);
59-
Assert.assertNotNull(result.accessToken());
60-
Assert.assertNotNull(result.idToken());
78+
Assert.assertNotNull(result3);
79+
Assert.assertNotNull(result3.accessToken());
80+
Assert.assertNotEquals(result2.accessToken(), result3.accessToken());
81+
82+
// Scope 2, should return cached token
83+
IAuthenticationResult result4 =
84+
cca.acquireToken(OnBehalfOfParameters.builder(
85+
Collections.singleton(cfg.graphDefaultScope()),
86+
new UserAssertion(accessToken)).build()).
87+
get();
88+
89+
Assert.assertEquals(result3.accessToken(), result4.accessToken());
90+
91+
// skipCache=true, should return new token
92+
IAuthenticationResult result5 =
93+
cca.acquireToken(
94+
OnBehalfOfParameters.builder(
95+
Collections.singleton(cfg.graphDefaultScope()),
96+
new UserAssertion(accessToken))
97+
.skipCache(true)
98+
.build()).
99+
get();
100+
101+
Assert.assertNotNull(result5);
102+
Assert.assertNotNull(result5.accessToken());
103+
Assert.assertNotEquals(result5.accessToken(), result4.accessToken());
104+
Assert.assertNotEquals(result5.accessToken(), result2.accessToken());
105+
106+
107+
String newAccessToken = this.getAccessToken();
108+
// New new UserAssertion, should return new token
109+
IAuthenticationResult result6 =
110+
cca.acquireToken(
111+
OnBehalfOfParameters.builder(
112+
Collections.singleton(cfg.graphDefaultScope()),
113+
new UserAssertion(newAccessToken))
114+
.build()).
115+
get();
116+
117+
Assert.assertNotNull(result6);
118+
Assert.assertNotNull(result6.accessToken());
119+
Assert.assertNotEquals(result6.accessToken(), result5.accessToken());
120+
Assert.assertNotEquals(result6.accessToken(), result4.accessToken());
121+
Assert.assertNotEquals(result6.accessToken(), result2.accessToken());
122+
}
123+
124+
private String getAccessToken() throws Exception {
125+
126+
LabUserProvider labUserProvider = LabUserProvider.getInstance();
127+
User user = labUserProvider.getDefaultUser(cfg.azureEnvironment);
128+
129+
String clientId = cfg.appProvider.getAppId();
130+
String apiReadScope = cfg.appProvider.getOboAppIdURI() + "/user_impersonation";
131+
PublicClientApplication pca = PublicClientApplication.builder(
132+
clientId).
133+
authority(cfg.tenantSpecificAuthority()).
134+
build();
135+
136+
IAuthenticationResult result = pca.acquireToken(
137+
UserNamePasswordParameters.builder(Collections.singleton(apiReadScope),
138+
user.getUpn(),
139+
user.getPassword().toCharArray()).build()).get();
140+
141+
return result.accessToken();
61142
}
62143
}

0 commit comments

Comments
 (0)