Skip to content

Commit 21f253e

Browse files
authored
using certificate from Key Vault for unit testing (#243)
using certificate from Key Vault for unit testing
1 parent 6deb186 commit 21f253e

File tree

12 files changed

+189
-253
lines changed

12 files changed

+189
-253
lines changed

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
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import java.net.MalformedURLException;
1313
import java.net.URI;
1414
import java.util.Collections;
15-
import java.util.HashSet;
1615
import java.util.Map;
1716
import java.util.HashMap;
1817
import java.util.Set;
@@ -181,7 +180,7 @@ private void assertAcquireTokenAAD(User user, Map<String, Set<String>> parameter
181180
private void assertAcquireTokenB2C(User user){
182181

183182
String appId = LabService.getSecret(TestConstants.B2C_CONFIDENTIAL_CLIENT_LAB_APP_ID);
184-
String appSecret = LabService.getSecret(TestConstants.B2C_CONFIDENTIAL_CLIENT_APP_SECRET);
183+
String appSecret = LabService.getSecret(TestConstants.B2C_CONFIDENTIAL_CLIENT_APP_SECRETID);
185184

186185
ConfidentialClientApplication cca;
187186
try {
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
}

src/test/java/com/microsoft/aad/msal4j/ConfidentialClientApplicationTest.java renamed to src/integrationtest/java/com.microsoft.aad.msal4j/ConfidentialClientApplicationUnitT.java

Lines changed: 27 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,48 @@
1111
import com.nimbusds.jwt.JWTClaimsSet;
1212
import com.nimbusds.jwt.SignedJWT;
1313
import com.nimbusds.oauth2.sdk.auth.PrivateKeyJWT;
14+
import org.apache.commons.lang3.StringUtils;
1415
import org.easymock.EasyMock;
1516
import org.powermock.api.easymock.PowerMock;
1617
import org.powermock.core.classloader.annotations.PowerMockIgnore;
1718
import org.powermock.core.classloader.annotations.PrepareForTest;
1819
import org.powermock.modules.testng.PowerMockTestCase;
1920
import org.testng.Assert;
21+
import org.testng.annotations.BeforeClass;
2022
import org.testng.annotations.Test;
2123

22-
import java.io.FileInputStream;
24+
import java.io.IOException;
2325
import java.net.URI;
24-
import java.security.KeyStore;
25-
import java.security.PrivateKey;
26-
import java.security.cert.X509Certificate;
27-
import java.util.ArrayList;
28-
import java.util.Collections;
29-
import java.util.Date;
30-
import java.util.List;
31-
import java.util.UUID;
26+
import java.security.*;
27+
import java.security.cert.CertificateException;
28+
import java.util.*;
3229
import java.util.concurrent.Future;
3330

3431
import static org.testng.Assert.assertFalse;
3532
import static org.testng.Assert.assertNotNull;
3633

3734
@PowerMockIgnore({"javax.net.ssl.*"})
38-
@Test(groups = {"checkin"})
3935
@PrepareForTest({ConfidentialClientApplication.class,
4036
ClientCertificate.class, UserDiscoveryRequest.class, JwtHelper.class})
41-
public class ConfidentialClientApplicationTest extends PowerMockTestCase {
37+
public class ConfidentialClientApplicationUnitT extends PowerMockTestCase {
4238

4339
private ConfidentialClientApplication app = null;
40+
private IClientCertificate clientCertificate;
41+
42+
@BeforeClass
43+
private void init() throws
44+
KeyStoreException, IOException, NoSuchAlgorithmException,
45+
CertificateException, UnrecoverableKeyException, NoSuchProviderException {
46+
47+
clientCertificate = CertificateHelper.getClientCertificate();
48+
}
4449

4550
@Test
4651
public void testAcquireTokenAuthCode_ClientCredential() throws Exception {
4752
app = PowerMock.createPartialMock(ConfidentialClientApplication.class,
4853
new String[]{"acquireTokenCommon"},
4954
ConfidentialClientApplication.builder(TestConfiguration.AAD_CLIENT_ID,
50-
ClientCredentialFactory.createFromSecret(TestConfiguration.AAD_CLIENT_SECRET))
55+
ClientCredentialFactory.createFromSecret(TestConfiguration.AAD_CLIENT_DUMMYSECRET))
5156
.authority(TestConfiguration.AAD_TENANT_ENDPOINT)
5257
);
5358

@@ -77,23 +82,9 @@ public void testAcquireTokenAuthCode_ClientCredential() throws Exception {
7782

7883
@Test
7984
public void testAcquireTokenAuthCode_KeyCredential() throws Exception {
80-
final KeyStore keystore = KeyStore.getInstance("PKCS12", "SunJSSE");
81-
keystore.load(
82-
new FileInputStream(this.getClass()
83-
.getResource(TestConfiguration.AAD_CERTIFICATE_PATH)
84-
.getFile()),
85-
TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
86-
final String alias = keystore.aliases().nextElement();
87-
final PrivateKey key = (PrivateKey) keystore.getKey(alias,
88-
TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
89-
final X509Certificate cert = (X509Certificate) keystore
90-
.getCertificate(alias);
91-
92-
IClientCredential clientCredential = ClientCredentialFactory.createFromCertificate(key, cert);
93-
9485
app = PowerMock.createPartialMock(ConfidentialClientApplication.class,
9586
new String[]{"acquireTokenCommon"},
96-
ConfidentialClientApplication.builder(TestConfiguration.AAD_CLIENT_ID, clientCredential)
87+
ConfidentialClientApplication.builder(TestConfiguration.AAD_CLIENT_ID, clientCertificate)
9788
.authority(TestConfiguration.AAD_TENANT_ENDPOINT));
9889

9990
PowerMock.expectPrivate(app, "acquireTokenCommon",
@@ -121,24 +112,11 @@ public void testAcquireTokenAuthCode_KeyCredential() throws Exception {
121112
PowerMock.resetAll(app);
122113
}
123114

115+
@Test
124116
public void testAcquireToken_KeyCred() throws Exception {
125-
final KeyStore keystore = KeyStore.getInstance("PKCS12", "SunJSSE");
126-
keystore.load(
127-
new FileInputStream(this.getClass()
128-
.getResource(TestConfiguration.AAD_CERTIFICATE_PATH)
129-
.getFile()),
130-
TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
131-
final String alias = keystore.aliases().nextElement();
132-
final PrivateKey key = (PrivateKey) keystore.getKey(alias,
133-
TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
134-
final X509Certificate cert = (X509Certificate) keystore
135-
.getCertificate(alias);
136-
137-
IClientCredential clientCredential = ClientCredentialFactory.createFromCertificate(key, cert);
138-
139117
app = PowerMock.createPartialMock(ConfidentialClientApplication.class,
140118
new String[]{"acquireTokenCommon"},
141-
ConfidentialClientApplication.builder(TestConfiguration.AAD_CLIENT_ID, clientCredential)
119+
ConfidentialClientApplication.builder(TestConfiguration.AAD_CLIENT_ID, clientCertificate)
142120
.authority(TestConfiguration.AAD_TENANT_ENDPOINT));
143121

144122
PowerMock.expectPrivate(app, "acquireTokenCommon",
@@ -167,23 +145,13 @@ public void testAcquireToken_KeyCred() throws Exception {
167145

168146
@Test
169147
public void testClientCertificateRebuildsWhenExpired() throws Exception {
170-
final KeyStore keystore = KeyStore.getInstance("PKCS12", "SunJSSE");
171-
keystore.load(
172-
new FileInputStream(this.getClass()
173-
.getResource(TestConfiguration.AAD_CERTIFICATE_PATH)
174-
.getFile()),
175-
TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
176-
final String alias = keystore.aliases().nextElement();
177-
final PrivateKey key = (PrivateKey) keystore.getKey(alias,
178-
TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
179-
final X509Certificate cert = (X509Certificate) keystore
180-
.getCertificate(alias);
181-
182-
ClientCertificate clientCredential = (ClientCertificate) ClientCredentialFactory.createFromCertificate(key, cert);
183-
184148
PowerMock.mockStaticPartial(JwtHelper.class, new String[]{"buildJwt"});
185149
long jwtExperiationPeriodMilli = 2000;
186-
ClientAssertion shortExperationJwt = buildShortJwt(TestConfiguration.AAD_CLIENT_ID, clientCredential, TestConfiguration.AAD_TENANT_ENDPOINT, jwtExperiationPeriodMilli);
150+
ClientAssertion shortExperationJwt = buildShortJwt(TestConfiguration.AAD_CLIENT_ID,
151+
clientCertificate,
152+
TestConfiguration.AAD_TENANT_ENDPOINT,
153+
jwtExperiationPeriodMilli);
154+
187155
PowerMock.expectPrivate(
188156
JwtHelper.class,
189157
"buildJwt",
@@ -194,7 +162,7 @@ public void testClientCertificateRebuildsWhenExpired() throws Exception {
194162
.times(2); // By this being called twice we ensure the client assertion is rebuilt once it has expired
195163

196164
PowerMock.replay(JwtHelper.class);
197-
app = ConfidentialClientApplication.builder(TestConfiguration.AAD_CLIENT_ID, clientCredential)
165+
app = ConfidentialClientApplication.builder(TestConfiguration.AAD_CLIENT_ID, clientCertificate)
198166
.authority(TestConfiguration.AAD_TENANT_ENDPOINT).build();
199167
Thread.sleep(jwtExperiationPeriodMilli + 1000); //Have to sleep to ensure that the time period has passed
200168
final PrivateKeyJWT clientAuthentication = (PrivateKeyJWT) app.clientAuthentication();
@@ -203,7 +171,7 @@ public void testClientCertificateRebuildsWhenExpired() throws Exception {
203171
}
204172

205173
private ClientAssertion buildShortJwt(String clientId,
206-
ClientCertificate credential,
174+
IClientCertificate credential,
207175
String jwtAudience,
208176
long jwtExperiationPeriod) {
209177
final long time = System.currentTimeMillis();

0 commit comments

Comments
 (0)