Skip to content

Commit 3b1d480

Browse files
committed
Add basic KeyVaultKeyResolver test
1 parent 393fc2b commit 3b1d480

File tree

4 files changed

+502
-14
lines changed

4 files changed

+502
-14
lines changed

services/keyvault/azure-keyvault-extensions/pom.xml

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@
5454
<dependency>
5555
<groupId>${project.groupId}</groupId>
5656
<artifactId>azure-keyvault</artifactId>
57+
<version>${project.version}</version>
5758
</dependency>
5859
<dependency>
5960
<groupId>${project.groupId}</groupId>
6061
<artifactId>azure-keyvault-core</artifactId>
62+
<version>${project.version}</version>
6163
</dependency>
6264
<dependency>
6365
<groupId>junit</groupId>
@@ -69,19 +71,38 @@
6971
<artifactId>bcprov-jdk16</artifactId>
7072
<scope>test</scope>
7173
</dependency>
74+
75+
<!-- Test dependencies -->
76+
<dependency>
77+
<groupId>${project.groupId}</groupId>
78+
<artifactId>azure-core-test</artifactId>
79+
<version>${project.version}</version>
80+
<scope>test</scope>
81+
</dependency>
82+
<dependency>
83+
<groupId>org.hamcrest</groupId>
84+
<artifactId>hamcrest-all</artifactId>
85+
<scope>test</scope>
86+
</dependency>
87+
<dependency>
88+
<groupId>org.mockito</groupId>
89+
<artifactId>mockito-all</artifactId>
90+
<scope>test</scope>
91+
</dependency>
92+
<dependency>
93+
<groupId>junit</groupId>
94+
<artifactId>junit</artifactId>
95+
<scope>test</scope>
96+
</dependency>
97+
<dependency>
98+
<groupId>org.bouncycastle</groupId>
99+
<artifactId>bcprov-jdk16</artifactId>
100+
<scope>test</scope>
101+
</dependency>
102+
<dependency>
103+
<groupId>com.github.tomakehurst</groupId>
104+
<artifactId>wiremock</artifactId>
105+
<scope>test</scope>
106+
</dependency>
72107
</dependencies>
73-
<dependencyManagement>
74-
<dependencies>
75-
<dependency>
76-
<groupId>${project.groupId}</groupId>
77-
<artifactId>azure-keyvault</artifactId>
78-
<version>${project.version}</version>
79-
</dependency>
80-
<dependency>
81-
<groupId>${project.groupId}</groupId>
82-
<artifactId>azure-keyvault-core</artifactId>
83-
<version>${project.version}</version>
84-
</dependency>
85-
</dependencies>
86-
</dependencyManagement>
87108
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/**
2+
*
3+
* Copyright (c) Microsoft and contributors. All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
*
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package com.microsoft.azure.keyvault.extensions.test;
20+
21+
import java.util.Map;
22+
import java.util.concurrent.Callable;
23+
import java.util.concurrent.ExecutorService;
24+
import java.util.concurrent.Executors;
25+
import java.util.concurrent.Future;
26+
27+
import org.apache.http.Header;
28+
import org.apache.http.message.BasicHeader;
29+
import org.codehaus.jackson.map.ObjectMapper;
30+
import org.codehaus.jackson.map.ObjectReader;
31+
import org.codehaus.jackson.map.ObjectWriter;
32+
import org.junit.After;
33+
import org.junit.AfterClass;
34+
import org.junit.Before;
35+
import org.junit.BeforeClass;
36+
37+
import com.microsoft.aad.adal4j.AuthenticationContext;
38+
import com.microsoft.aad.adal4j.AuthenticationResult;
39+
import com.microsoft.aad.adal4j.ClientCredential;
40+
import com.microsoft.azure.keyvault.KeyVaultClient;
41+
import com.microsoft.azure.keyvault.KeyVaultClientService;
42+
import com.microsoft.azure.keyvault.KeyVaultConfiguration;
43+
import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials;
44+
import com.microsoft.windowsazure.Configuration;
45+
import com.microsoft.windowsazure.MockIntegrationTestBase;
46+
import com.microsoft.windowsazure.core.pipeline.filter.ServiceRequestContext;
47+
import com.microsoft.windowsazure.credentials.CloudCredentials;
48+
import com.microsoft.windowsazure.credentials.TokenCloudCredentials;
49+
50+
public class KeyVaultExtensionsIntegrationTestBase extends MockIntegrationTestBase {
51+
52+
/**
53+
* The client instance that should be used on tests.
54+
*/
55+
protected static KeyVaultClient keyVaultClient;
56+
57+
/**
58+
* <code>true</code> if current client instance can handle 401 from service,
59+
* <code>false</code> otherwise.
60+
*/
61+
protected static boolean handling401;
62+
63+
/**
64+
* Primary vault URI, used for keys and secrets tests.
65+
*/
66+
public static String getVaultUri() {
67+
return IS_MOCKED ? MOCK_URI : getLiveVaultUri1();
68+
}
69+
70+
/**
71+
* Secondary vault URI, used to verify ability to transparently authenticate
72+
* against a different resource.
73+
*/
74+
public static String getSecondaryVaultUri() {
75+
return IS_MOCKED ? MOCK_URI : getLiveVaultUri2();
76+
}
77+
78+
private static String getLiveVaultUri1() {
79+
return getenvOrDefault("keyvault.vaulturi", "https://javasdktestvault.vault.azure.net");
80+
}
81+
82+
private static String getLiveVaultUri2() {
83+
return getenvOrDefault("keyvault.vaulturi.alt", "https://javasdktestvault2.vault.azure.net");
84+
}
85+
86+
private static String getenvOrDefault(String varName, String defValue) {
87+
String value = System.getenv(varName);
88+
return value != null ? value : defValue;
89+
}
90+
91+
protected static void createKeyVaultClient() throws Exception {
92+
Configuration config = createConfiguration();
93+
94+
keyVaultClient = KeyVaultClientService.create(config);
95+
addClient(keyVaultClient.getServiceClient(), new Callable<Void>() {
96+
@Override
97+
public Void call() throws Exception {
98+
createKeyVaultClient();
99+
return null;
100+
}
101+
});
102+
addRegexRule(getLiveVaultUri1(), MOCK_URI);
103+
addRegexRule(getLiveVaultUri2(), MOCK_URI);
104+
}
105+
106+
public static Configuration createConfiguration() throws Exception {
107+
return KeyVaultConfiguration.configure(null, createTestCredentials());
108+
}
109+
110+
private static CloudCredentials createTestCredentials() throws Exception {
111+
112+
handling401 = false;
113+
114+
if (IS_MOCKED) {
115+
// When mocked, there's no authentication.
116+
return new TokenCloudCredentials(null, MOCK_SUBSCRIPTION, null);
117+
}
118+
119+
boolean preAuthenticate = "true".equalsIgnoreCase(System.getenv("arm.preauthenticate"));
120+
121+
if (preAuthenticate) {
122+
String authorization = System.getenv("arm.aad.url") + System.getenv("arm.tenant");
123+
String resource = System.getenv("arm.resource");
124+
String subscriptionId = System.getenv("arm.subscriptionid");
125+
return new TokenCloudCredentials(null, subscriptionId, getAccessToken(authorization, resource).getAccessToken());
126+
}
127+
128+
handling401 = true;
129+
return new KeyVaultCredentials() {
130+
131+
@Override
132+
public Header doAuthenticate(ServiceRequestContext request, Map<String, String> challenge) {
133+
try {
134+
String authorization = challenge.get("authorization");
135+
String resource = challenge.get("resource");
136+
AuthenticationResult authResult = getAccessToken(authorization, resource);
137+
return new BasicHeader("Authorization", authResult.getAccessTokenType() + " " + authResult.getAccessToken());
138+
} catch (Exception ex) {
139+
throw new RuntimeException(ex);
140+
}
141+
}
142+
};
143+
}
144+
145+
private static AuthenticationResult getAccessToken(String authorization, String resource) throws Exception {
146+
147+
String clientId = System.getenv("arm.clientid");
148+
if (clientId == null) {
149+
throw new Exception("Please inform arm.clientid in the environment settings.");
150+
}
151+
152+
String clientKey = System.getenv("arm.clientkey");
153+
String username = System.getenv("arm.username");
154+
String password = System.getenv("arm.password");
155+
156+
AuthenticationResult result = null;
157+
ExecutorService service = null;
158+
try {
159+
service = Executors.newFixedThreadPool(1);
160+
AuthenticationContext context = new AuthenticationContext(authorization, false, service);
161+
162+
Future<AuthenticationResult> future = null;
163+
164+
if (clientKey != null && password == null) {
165+
ClientCredential credentials = new ClientCredential(clientId, clientKey);
166+
future = context.acquireToken(resource, credentials, null);
167+
}
168+
169+
if (password != null && clientKey == null) {
170+
future = context.acquireToken(resource, clientId, username, password, null);
171+
}
172+
173+
if (future == null) {
174+
throw new Exception("Missing or ambiguous credentials - please inform exactly one of arm.clientkey or arm.password in the environment settings.");
175+
}
176+
177+
result = future.get();
178+
} finally {
179+
service.shutdown();
180+
}
181+
182+
if (result == null) {
183+
throw new RuntimeException("authentication result was null");
184+
}
185+
return result;
186+
}
187+
188+
protected static ObjectWriter jsonWriter;
189+
protected static ObjectReader jsonReader;
190+
191+
@BeforeClass
192+
public static void setup() throws Exception {
193+
createKeyVaultClient();
194+
jsonWriter = new ObjectMapper().writer().withDefaultPrettyPrinter();
195+
jsonReader = new ObjectMapper().reader();
196+
}
197+
198+
@AfterClass
199+
public static void cleanup() throws Exception {
200+
}
201+
202+
@Before
203+
public void beforeTest() throws Exception {
204+
setupTest(getClass().getSimpleName() + "-" + name.getMethodName());
205+
}
206+
207+
@After
208+
public void afterTest() throws Exception {
209+
resetTest(getClass().getSimpleName() + "-" + name.getMethodName());
210+
}
211+
212+
}

0 commit comments

Comments
 (0)