Skip to content

Commit 36c8796

Browse files
authored
Merge pull request #245 from AzureAD/dev
1.6 release
2 parents dfb6c26 + b8e1551 commit 36c8796

40 files changed

+519
-340
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Quick links:
1616
The library supports the following Java environments:
1717
- Java 8 (or higher)
1818

19-
Current version - 1.5.0
19+
Current version - 1.6.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.5.0</version>
31+
<version>1.6.0</version>
3232
</dependency>
3333
```
3434
### Gradle
3535

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

4040
## Usage

build/credscan-exclude.json

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,5 @@
11
{
22
"tool": "Credential Scanner",
33
"suppressions": [
4-
{
5-
"file": "test-certificate.pfx",
6-
"_justification": "test self signed certificate to test signing from the library. this certificate is not associated with any tenant"
7-
},
8-
{
9-
"placeholder": "client_secret",
10-
"_justification" : "credential used for testing. not associated with any tenant"
11-
},
12-
{
13-
"placeholder": "ClientPassword",
14-
"_justification" : "credential used for testing. not associated with any tenant"
15-
},
16-
{
17-
"placeholder": "B2C_CONFIDENTIAL_CLIENT_APP_SECRET",
18-
"_justification" : "Not a credential, just the identifier of the secret exposed by test lab API"
19-
},
20-
{
21-
"placeholder": "MSIDLABB2C-MSAapp-AppSecret",
22-
"_justification" : "Not a credential, just the identifier of the secret exposed by test lab API"
23-
}
244
]
255
}

changelog.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Version 1.6.0
2+
=============
3+
- Client capabilities support
4+
- Enable device code flow for ADFS2019
5+
- Fix dependency issues with jackson 2.6.7 and json-smart 1.3.1
6+
17
Version 1.5.0
28
=============
39
- Support of server side throttling instructions

lombok.config

Lines changed: 0 additions & 1 deletion
This file was deleted.

pom.xml

Lines changed: 1 addition & 1 deletion
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.5.0</version>
6+
<version>1.6.0</version>
77
<packaging>jar</packaging>
88
<name>msal4j</name>
99
<description>

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

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import java.net.MalformedURLException;
1313
import java.net.URI;
1414
import java.util.Collections;
15+
import java.util.Map;
16+
import java.util.HashMap;
1517
import java.util.Set;
1618
import java.util.concurrent.BlockingQueue;
1719
import java.util.concurrent.LinkedBlockingQueue;
@@ -27,7 +29,22 @@ public void acquireTokenWithAuthorizationCode_ManagedUser(String environment){
2729
cfg = new Config(environment);
2830

2931
User user = labUserProvider.getDefaultUser(cfg.azureEnvironment);
30-
assertAcquireTokenAAD(user);
32+
assertAcquireTokenAAD(user, null);
33+
}
34+
35+
//TODO: Re-enable test once list of claims/capabilities and their expected behavior is known
36+
//@Test(dataProvider = "environments", dataProviderClass = EnvironmentsProvider.class)
37+
public void acquireTokenWithAuthorizationCode_ManagedUserWithClaimsAndCapabilities(String environment){
38+
cfg = new Config(environment);
39+
40+
User user = labUserProvider.getDefaultUser(cfg.azureEnvironment);
41+
42+
Map<String, Set<String>> claimsAndCapabilities = new HashMap<>();
43+
44+
claimsAndCapabilities.put("claims", Collections.singleton(TestConstants.CLAIMS));
45+
claimsAndCapabilities.put("clientCapabilities", TestConstants.CLIENT_CAPABILITIES_EMPTY);
46+
47+
assertAcquireTokenAAD(user, claimsAndCapabilities);
3148
}
3249

3350
@Test
@@ -41,7 +58,7 @@ public void acquireTokenWithAuthorizationCode_ADFSv2019_Federated(String environ
4158
cfg = new Config(environment);
4259

4360
User user = labUserProvider.getFederatedAdfsUser(cfg.azureEnvironment, FederationProvider.ADFS_2019);
44-
assertAcquireTokenAAD(user);
61+
assertAcquireTokenAAD(user, null);
4562
}
4663

4764
@Test(dataProvider = "environments", dataProviderClass = EnvironmentsProvider.class)
@@ -50,23 +67,23 @@ public void acquireTokenWithAuthorizationCode_ADFSv4_Federated(String environmen
5067

5168
User user = labUserProvider.getFederatedAdfsUser(cfg.azureEnvironment, FederationProvider.ADFS_4);
5269

53-
assertAcquireTokenAAD(user);
70+
assertAcquireTokenAAD(user, null);
5471
}
5572

5673
@Test(dataProvider = "environments", dataProviderClass = EnvironmentsProvider.class)
5774
public void acquireTokenWithAuthorizationCode_ADFSv3_Federated(String environment){
5875
cfg = new Config(environment);
5976

6077
User user = labUserProvider.getFederatedAdfsUser(cfg.azureEnvironment, FederationProvider.ADFS_3);
61-
assertAcquireTokenAAD(user);
78+
assertAcquireTokenAAD(user, null);
6279
}
6380

6481
@Test(dataProvider = "environments", dataProviderClass = EnvironmentsProvider.class)
6582
public void acquireTokenWithAuthorizationCode_ADFSv2_Federated(String environment){
6683
cfg = new Config(environment);
6784

6885
User user = labUserProvider.getFederatedAdfsUser(cfg.azureEnvironment, FederationProvider.ADFS_2);
69-
assertAcquireTokenAAD(user);
86+
assertAcquireTokenAAD(user, null);
7087
}
7188

7289
@Test(dataProvider = "environments", dataProviderClass = EnvironmentsProvider.class)
@@ -119,7 +136,7 @@ private void assertAcquireTokenADFS2019(User user){
119136
throw new RuntimeException(ex.getMessage());
120137
}
121138

122-
String authCode = acquireAuthorizationCodeAutomated(user, pca);
139+
String authCode = acquireAuthorizationCodeAutomated(user, pca, null);
123140
IAuthenticationResult result = acquireTokenAuthorizationCodeFlow(
124141
pca,
125142
authCode,
@@ -131,19 +148,24 @@ private void assertAcquireTokenADFS2019(User user){
131148
Assert.assertEquals(user.getUpn(), result.account().username());
132149
}
133150

134-
private void assertAcquireTokenAAD(User user){
151+
private void assertAcquireTokenAAD(User user, Map<String, Set<String>> parameters){
135152

136153
PublicClientApplication pca;
154+
Set<String> clientCapabilities = null;
155+
if (parameters != null) {
156+
clientCapabilities = parameters.getOrDefault("clientCapabilities", null);
157+
}
137158
try {
138-
pca = PublicClientApplication.builder(
139-
user.getAppId()).
140-
authority(cfg.organizationsAuthority()).
141-
build();
159+
pca = PublicClientApplication.builder(
160+
user.getAppId()).
161+
authority(cfg.organizationsAuthority()).
162+
clientCapabilities(clientCapabilities).
163+
build();
142164
} catch(MalformedURLException ex){
143165
throw new RuntimeException(ex.getMessage());
144166
}
145167

146-
String authCode = acquireAuthorizationCodeAutomated(user, pca);
168+
String authCode = acquireAuthorizationCodeAutomated(user, pca, parameters);
147169
IAuthenticationResult result = acquireTokenAuthorizationCodeFlow(
148170
pca,
149171
authCode,
@@ -158,7 +180,7 @@ private void assertAcquireTokenAAD(User user){
158180
private void assertAcquireTokenB2C(User user){
159181

160182
String appId = LabService.getSecret(TestConstants.B2C_CONFIDENTIAL_CLIENT_LAB_APP_ID);
161-
String appSecret = LabService.getSecret(TestConstants.B2C_CONFIDENTIAL_CLIENT_APP_SECRET);
183+
String appSecret = LabService.getSecret(TestConstants.B2C_CONFIDENTIAL_CLIENT_APP_SECRETID);
162184

163185
ConfidentialClientApplication cca;
164186
try {
@@ -171,7 +193,7 @@ private void assertAcquireTokenB2C(User user){
171193
throw new RuntimeException(ex.getMessage());
172194
}
173195

174-
String authCode = acquireAuthorizationCodeAutomated(user, cca);
196+
String authCode = acquireAuthorizationCodeAutomated(user, cca, null);
175197
IAuthenticationResult result = acquireTokenInteractiveB2C(cca, authCode);
176198

177199
Assert.assertNotNull(result);
@@ -218,7 +240,8 @@ private IAuthenticationResult acquireTokenInteractiveB2C(ConfidentialClientAppli
218240

219241
private String acquireAuthorizationCodeAutomated(
220242
User user,
221-
AbstractClientApplicationBase app){
243+
AbstractClientApplicationBase app,
244+
Map<String, Set<String>> parameters){
222245

223246
BlockingQueue<AuthorizationResult> authorizationCodeQueue = new LinkedBlockingQueue<>();
224247

@@ -231,7 +254,7 @@ private String acquireAuthorizationCodeAutomated(
231254

232255
AuthorizationResult result = null;
233256
try {
234-
String url = buildAuthenticationCodeURL(app);
257+
String url = buildAuthenticationCodeURL(app, parameters);
235258
seleniumDriver.navigate().to(url);
236259
runSeleniumAutomatedLogin(user, app);
237260

@@ -256,9 +279,15 @@ private String acquireAuthorizationCodeAutomated(
256279
}
257280
return result.code();
258281
}
259-
private String buildAuthenticationCodeURL(AbstractClientApplicationBase app) {
282+
283+
private String buildAuthenticationCodeURL(AbstractClientApplicationBase app, Map<String, Set<String>> parameters) {
260284
String scope;
261285

286+
String claims = null;
287+
if (parameters != null) {
288+
claims = String.valueOf(parameters.getOrDefault("claims", Collections.singleton("")).toArray()[0]);
289+
}
290+
262291
AuthorityType authorityType= app.authenticationAuthority.authorityType;
263292
if(authorityType == AuthorityType.AAD){
264293
scope = TestConstants.GRAPH_DEFAULT_SCOPE;
@@ -272,12 +301,13 @@ else if (authorityType == AuthorityType.ADFS){
272301
throw new RuntimeException("Authority type not recognized");
273302
}
274303

275-
AuthorizationRequestUrlParameters parameters =
304+
AuthorizationRequestUrlParameters authParameters =
276305
AuthorizationRequestUrlParameters
277306
.builder(TestConstants.LOCALHOST + httpListener.port(),
278307
Collections.singleton(scope))
308+
.claimsChallenge(claims)
279309
.build();
280310

281-
return app.getAuthorizationRequestUrl(parameters).toString();
311+
return app.getAuthorizationRequestUrl(authParameters).toString();
282312
}
283313
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.aad.msal4j;
5+
6+
import labapi.KeyVaultSecretsProvider;
7+
import org.apache.commons.lang3.SystemUtils;
8+
9+
import java.io.IOException;
10+
import java.security.*;
11+
import java.security.cert.CertificateException;
12+
import java.security.cert.X509Certificate;
13+
14+
public class CertificateHelper {
15+
static KeyStore createKeyStore() throws KeyStoreException, NoSuchProviderException {
16+
String os = SystemUtils.OS_NAME;
17+
if(os.contains("Mac")){
18+
return KeyStore.getInstance("KeychainStore");
19+
}
20+
else{
21+
return KeyStore.getInstance("Windows-MY", "SunMSCAPI");
22+
}
23+
}
24+
25+
static IClientCertificate getClientCertificate() throws
26+
KeyStoreException, IOException, NoSuchAlgorithmException,
27+
CertificateException, UnrecoverableKeyException, NoSuchProviderException {
28+
29+
KeyStore keystore = createKeyStore();
30+
31+
keystore.load(null, null);
32+
33+
PrivateKey key = (PrivateKey) keystore.getKey(KeyVaultSecretsProvider.CERTIFICATE_ALIAS, null);
34+
X509Certificate publicCertificate = (X509Certificate) keystore.getCertificate(
35+
KeyVaultSecretsProvider.CERTIFICATE_ALIAS);
36+
37+
return ClientCredentialFactory.createFromCertificate(key, publicCertificate);
38+
}
39+
}

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

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,33 @@
55

66
import labapi.AppCredentialProvider;
77
import labapi.AzureEnvironment;
8-
import labapi.KeyVaultSecretsProvider;
98
import org.testng.Assert;
9+
import org.testng.annotations.BeforeClass;
1010
import org.testng.annotations.Test;
1111

1212
import java.io.IOException;
13-
import java.security.KeyStore;
1413
import java.security.KeyStoreException;
1514
import java.security.NoSuchAlgorithmException;
1615
import java.security.NoSuchProviderException;
17-
import java.security.PrivateKey;
1816
import java.security.UnrecoverableKeyException;
1917
import java.security.cert.CertificateException;
20-
import java.security.cert.X509Certificate;
2118
import java.util.Collections;
2219

2320
import static com.microsoft.aad.msal4j.TestConstants.KEYVAULT_DEFAULT_SCOPE;
2421

2522
@Test
2623
public class ClientCredentialsIT {
24+
private IClientCertificate certificate;
25+
26+
@BeforeClass
27+
void init() throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, NoSuchProviderException, IOException {
28+
certificate = CertificateHelper.getClientCertificate();
29+
}
2730

2831
@Test
2932
public void acquireTokenClientCredentials_ClientCertificate() throws Exception{
3033
String clientId = "55e7e5af-ca53-482d-9aa3-5cb1cc8eecb5";
31-
IClientCredential credential = getCertificateFromKeyStore();
32-
assertAcquireTokenCommon(clientId, credential);
34+
assertAcquireTokenCommon(clientId, certificate);
3335
}
3436

3537
@Test
@@ -45,11 +47,10 @@ public void acquireTokenClientCredentials_ClientSecret() throws Exception{
4547
@Test
4648
public void acquireTokenClientCredentials_ClientAssertion() throws Exception{
4749
String clientId = "55e7e5af-ca53-482d-9aa3-5cb1cc8eecb5";
48-
IClientCredential certificateFromKeyStore = getCertificateFromKeyStore();
4950

5051
ClientAssertion clientAssertion = JwtHelper.buildJwt(
5152
clientId,
52-
(ClientCertificate) certificateFromKeyStore,
53+
(ClientCertificate) certificate,
5354
"https://login.microsoftonline.com/common/oauth2/v2.0/token");
5455

5556
IClientCredential credential = ClientCredentialFactory.createFromClientAssertion(
@@ -72,17 +73,4 @@ private void assertAcquireTokenCommon(String clientId, IClientCredential credent
7273
Assert.assertNotNull(result);
7374
Assert.assertNotNull(result.accessToken());
7475
}
75-
76-
private IClientCredential getCertificateFromKeyStore() throws
77-
NoSuchProviderException, KeyStoreException, IOException, NoSuchAlgorithmException,
78-
CertificateException, UnrecoverableKeyException {
79-
KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
80-
keystore.load(null, null);
81-
82-
PrivateKey key = (PrivateKey)keystore.getKey(KeyVaultSecretsProvider.CERTIFICATE_ALIAS, null);
83-
X509Certificate publicCertificate = (X509Certificate)keystore.getCertificate(
84-
KeyVaultSecretsProvider.CERTIFICATE_ALIAS);
85-
86-
return ClientCredentialFactory.createFromCertificate(key, publicCertificate);
87-
}
8876
}

0 commit comments

Comments
 (0)