Skip to content

Commit

Permalink
Merge pull request #457 from AzureAD/retrofit-security-vulnerabilities
Browse files Browse the repository at this point in the history
Remove transitive dependency on retrofit.
  • Loading branch information
siddhijain authored Jan 20, 2022
2 parents 79cd12d + b74cb55 commit 0288e7c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 35 deletions.
11 changes: 8 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,16 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-keyvault</artifactId>
<version>1.2.1</version>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-secrets</artifactId>
<version>4.3.5</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
public class TestConstants {
public final static String KEYVAULT_DEFAULT_SCOPE = "https://vault.azure.net/.default";
public final static String MSIDLAB_DEFAULT_SCOPE = "https://msidlab.com/.default";
public final static String MSIDLAB_VAULT_URL = "https://msidlabs.vault.azure.net/";
public final static String GRAPH_DEFAULT_SCOPE = "https://graph.windows.net/.default";
public final static String USER_READ_SCOPE = "user.read";
public final static String B2C_LAB_SCOPE = "https://msidlabb2c.onmicrosoft.com/msaapp/user_impersonation";
Expand Down
73 changes: 41 additions & 32 deletions src/integrationtest/java/labapi/KeyVaultSecretsProvider.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package labapi;

import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.security.keyvault.secrets.models.KeyVaultSecretIdentifier;
import com.microsoft.aad.msal4j.*;
import com.microsoft.azure.keyvault.KeyVaultClient;
import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials;
import reactor.core.publisher.Mono;

import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class KeyVaultSecretsProvider {

private final KeyVaultClient keyVaultClient;
private final SecretClient secretClient;

private static final String CLIENT_ID = "55e7e5af-ca53-482d-9aa3-5cb1cc8eecb5";
public static String CERTIFICATE_ALIAS = "MsalJavaAutomationRunner";

Expand All @@ -25,50 +29,54 @@ public class KeyVaultSecretsProvider {

private static final String MAC_KEYSTORE = "KeychainStore";

KeyVaultSecretsProvider() {
keyVaultClient = getAuthenticatedKeyVaultClient();
}

static Map<String, String> cache = new ConcurrentHashMap<>();

KeyVaultSecretsProvider(){
secretClient = getAuthenticatedSecretClient();
}

String getSecret(String secretUrl) {
if (cache.containsKey(secretUrl)) {
return cache.get(secretUrl);

// extract keyName from secretUrl
KeyVaultSecretIdentifier keyVaultSecretIdentifier = new KeyVaultSecretIdentifier(secretUrl);
String key = keyVaultSecretIdentifier.getName();

if (cache.containsKey(key)) {
return cache.get(key);
}
String secret = keyVaultClient.getSecret(secretUrl).value();
cache.put(secretUrl, secret);

String secret = secretClient.getSecret(key).getValue();
cache.put(key, secret);

return secret;
}

private KeyVaultClient getAuthenticatedKeyVaultClient() {
return new KeyVaultClient(
new KeyVaultCredentials() {
@Override
public String doAuthenticate(String authorization, String resource, String scope) {
return requestAccessTokenForAutomation();
}
});
private SecretClient getAuthenticatedSecretClient(){

SecretClient client = new SecretClientBuilder()
.credential(getTokenCredential())
.vaultUrl(TestConstants.MSIDLAB_VAULT_URL)
.buildClient();

return client;
}

private String requestAccessTokenForAutomation() {
private AccessToken requestAccessTokenForAutomation() {
IAuthenticationResult result;
try {
ConfidentialClientApplication cca = ConfidentialClientApplication.builder(
CLIENT_ID, getClientCredentialFromKeyStore()).
CLIENT_ID, getClientCredentialFromKeyStore()).
authority(TestConstants.MICROSOFT_AUTHORITY).
build();

result = cca.acquireToken(ClientCredentialParameters
.builder(Collections.singleton(TestConstants.KEYVAULT_DEFAULT_SCOPE))
.build()).
.builder(Collections.singleton(TestConstants.KEYVAULT_DEFAULT_SCOPE))
.build()).
get();

} catch (Exception e) {
throw new RuntimeException("Error acquiring token from Azure AD: " + e.getMessage());
}
if (result != null) {
return result.accessToken();
return new AccessToken(result.accessToken(), OffsetDateTime.ofInstant(result.expiresOnDate().toInstant(), ZoneOffset.UTC));
} else {
throw new NullPointerException("Authentication result is null");
}
Expand All @@ -79,7 +87,6 @@ private IClientCredential getClientCredentialFromKeyStore() {
X509Certificate publicCertificate;
try {
String os = System.getProperty("os.name");

KeyStore keystore;
if (os.toLowerCase().contains("windows")) {
keystore = KeyStore.getInstance(WIN_KEYSTORE, KEYSTORE_PROVIDER);
Expand All @@ -88,14 +95,16 @@ private IClientCredential getClientCredentialFromKeyStore() {
}

keystore.load(null, null);

key = (PrivateKey) keystore.getKey(CERTIFICATE_ALIAS, null);
publicCertificate = (X509Certificate) keystore.getCertificate(
CERTIFICATE_ALIAS);

} catch (Exception e) {
throw new RuntimeException("Error getting certificate from keystore: " + e.getMessage());
}
return ClientCredentialFactory.createFromCertificate(key, publicCertificate);
}

private TokenCredential getTokenCredential() {
return tokenRequestContext -> Mono.defer(() -> Mono.just(requestAccessTokenForAutomation()));
}
}

0 comments on commit 0288e7c

Please sign in to comment.