Skip to content

Add support for passing access tokens to com.azure.security.keyvault.jca for use in Azure devops #44878

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ public KeyVaultKeyStore() {
String clientId = System.getProperty("azure.keyvault.client-id");
String clientSecret = System.getProperty("azure.keyvault.client-secret");
String managedIdentity = System.getProperty("azure.keyvault.managed-identity");
String accessToken = System.getProperty("azure.keyvault.access-token");
boolean disableChallengeResourceVerification
= Boolean.parseBoolean(System.getProperty("azure.keyvault.disable-challenge-resource-verification"));
long refreshInterval = getRefreshInterval();
Expand All @@ -146,7 +147,7 @@ public KeyVaultKeyStore() {
LOGGER.log(FINE, String.format("Loaded custom certificates: %s.", customCertificates.getAliases()));

keyVaultCertificates = new KeyVaultCertificates(refreshInterval, keyVaultUri, tenantId, clientId, clientSecret,
managedIdentity, disableChallengeResourceVerification);
managedIdentity, accessToken, disableChallengeResourceVerification);
LOGGER.log(FINE, String.format("Loaded Key Vault certificates: %s.", keyVaultCertificates.getAliases()));

classpathCertificates = new ClasspathCertificates();
Expand Down Expand Up @@ -399,7 +400,7 @@ public void engineLoad(KeyStore.LoadStoreParameter param) {

keyVaultCertificates.updateKeyVaultClient(parameter.getUri(), parameter.getTenantId(),
parameter.getClientId(), parameter.getClientSecret(), parameter.getManagedIdentity(),
parameter.isChallengeResourceVerificationDisabled());
parameter.getAccessToken(), parameter.isChallengeResourceVerificationDisabled());
}

classpathCertificates.loadCertificatesFromClasspath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public final class KeyVaultLoadStoreParameter implements KeyStore.LoadStoreParam
*/
private final String managedIdentity;

/*
* Stores the access token which can be obtained using powershell command: ( az account get-access-token --scope https://vault.azure.net/.default | ConvertFrom-Json ).accessToken
*/
private final String accessToken;

/**
* Stores a flag indicating if challenge resource verification shall be disabled.
*/
Expand Down Expand Up @@ -83,12 +88,28 @@ public KeyVaultLoadStoreParameter(String keyVaultUri, String tenantId, String cl
*/
public KeyVaultLoadStoreParameter(String keyVaultUri, String tenantId, String clientId, String clientSecret,
String managedIdentity) {
this(keyVaultUri, tenantId, clientId, clientSecret, managedIdentity, null);
}

/**
* Constructor.
*
* @param keyVaultUri The Azure Key Vault URI.
* @param tenantId The tenant id.
* @param clientId The client id.
* @param clientSecret The client secret.
* @param managedIdentity The managed identity.
* @param accessToken The access token.
*/
public KeyVaultLoadStoreParameter(String keyVaultUri, String tenantId, String clientId, String clientSecret,
String managedIdentity, String accessToken) {

this.keyVaultUri = keyVaultUri;
this.tenantId = tenantId;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.managedIdentity = managedIdentity;
this.accessToken = accessToken;
}

/**
Expand Down Expand Up @@ -146,6 +167,15 @@ public String getUri() {
return keyVaultUri;
}

/**
* Get the access token which can be obtained using powershell command: ( az account get-access-token --scope https://vault.azure.net/.default | ConvertFrom-Json ).accessToken
*
* @return The access token.
*/
public String getAccessToken() {
return accessToken;
}

/**
* Get a value indicating a check verifying if the authentication challenge resource matches the Key Vault or
* Managed HSM domain will be performed. This verification is performed by default.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public class KeyVaultClient {
*/
private final String clientSecret;

/*
* Stores the access token as it was passed as parameter to this class
*/
private final AccessToken configuredAccessToken;

/**
* Stores the managed identity (either the user-assigned managed identity object ID or null if system-assigned).
*/
Expand All @@ -106,7 +111,17 @@ public class KeyVaultClient {
* @param managedIdentity The user-assigned managed identity object ID.
*/
KeyVaultClient(String keyVaultUri, String managedIdentity) {
this(keyVaultUri, null, null, null, managedIdentity, false);
this(keyVaultUri, null, null, null, managedIdentity, null, false);
}

/**
* Constructor for authentication with user-assigned managed identity.
*
* @param keyVaultUri The Azure Key Vault URI.
* @param accessToken The access token to use.
*/
KeyVaultClient(String keyVaultUri, AccessToken accessToken) {
this(keyVaultUri, null, null, null, null, accessToken, false);
}

/**
Expand All @@ -118,7 +133,7 @@ public class KeyVaultClient {
* @param clientSecret The client secret.
*/
public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, String clientSecret) {
this(keyVaultUri, tenantId, clientId, clientSecret, null, false);
this(keyVaultUri, tenantId, clientId, clientSecret, null, null, false);
}

/**
Expand All @@ -129,10 +144,11 @@ public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, Stri
* @param clientId The client ID.
* @param clientSecret The client secret.
* @param managedIdentity The user-assigned managed identity object ID.
* @param accessToken The access token to use.
* @param disableChallengeResourceVerification Indicates if the challenge resource verification should be disabled.
*/
public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, String clientSecret,
String managedIdentity, boolean disableChallengeResourceVerification) {
String managedIdentity, AccessToken accessToken, boolean disableChallengeResourceVerification) {

LOGGER.log(INFO, "Using Azure Key Vault: {0}", keyVaultUri);

Expand All @@ -147,6 +163,7 @@ public KeyVaultClient(String keyVaultUri, String tenantId, String clientId, Stri
this.clientId = clientId;
this.clientSecret = clientSecret;
this.managedIdentity = managedIdentity;
this.configuredAccessToken = accessToken;
this.disableChallengeResourceVerification = disableChallengeResourceVerification;
}

Expand All @@ -156,10 +173,19 @@ public static KeyVaultClient createKeyVaultClientBySystemProperty() {
String clientId = System.getProperty("azure.keyvault.client-id");
String clientSecret = System.getProperty("azure.keyvault.client-secret");
String managedIdentity = System.getProperty("azure.keyvault.managed-identity");
String accessTokenAsString = System.getProperty("azure.keyvault.access-token");
boolean disableChallengeResourceVerification
= Boolean.parseBoolean(System.getProperty("azure.keyvault.disable-challenge-resource-verification"));

return new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret, managedIdentity,
AccessToken accessToken = null;

if (accessTokenAsString != null && !accessTokenAsString.isEmpty()) {
accessToken = new AccessToken();
accessToken.setAccessToken(accessTokenAsString);
accessToken.setExpiresIn(240);
}

return new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret, managedIdentity, accessToken,
disableChallengeResourceVerification);
}

Expand Down Expand Up @@ -200,6 +226,8 @@ private AccessToken getAccessTokenByHttpRequest() {
disableChallengeResourceVerification);
accessToken
= AccessTokenUtil.getAccessToken(resource, aadAuthenticationUri, tenantId, clientId, clientSecret);
} else if (configuredAccessToken != null) {
accessToken = configuredAccessToken;
} else {
accessToken = AccessTokenUtil.getAccessToken(resource, managedIdentity);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package com.azure.security.keyvault.jca.implementation.certificates;

import com.azure.security.keyvault.jca.implementation.KeyVaultClient;
import com.azure.security.keyvault.jca.implementation.model.AccessToken;

import java.security.Key;
import java.security.cert.Certificate;
Expand Down Expand Up @@ -50,11 +51,11 @@ public final class KeyVaultCertificates implements AzureCertificates {
private final long refreshInterval;

public KeyVaultCertificates(long refreshInterval, String keyVaultUri, String tenantId, String clientId,
String clientSecret, String managedIdentity, boolean disableChallengeResourceVerification) {
String clientSecret, String managedIdentity, String accessToken, boolean disableChallengeResourceVerification) {

this.refreshInterval = refreshInterval;

updateKeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret, managedIdentity,
updateKeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret, managedIdentity, accessToken,
disableChallengeResourceVerification);
}

Expand All @@ -71,14 +72,23 @@ public KeyVaultCertificates(long refreshInterval, KeyVaultClient keyVaultClient)
* @param clientId Client ID.
* @param clientSecret Client secret.
* @param managedIdentity Managed identity.
* @param accessToken Access token.
* @param disableChallengeResourceVerification Indicates if the challenge resource verification should be disabled.
*/
public void updateKeyVaultClient(String keyVaultUri, String tenantId, String clientId, String clientSecret,
String managedIdentity, boolean disableChallengeResourceVerification) {
String managedIdentity, String accessToken, boolean disableChallengeResourceVerification) {

AccessToken theAccessToken = null;

if (accessToken != null && !accessToken.isEmpty()) {
theAccessToken = new AccessToken();
theAccessToken.setAccessToken(accessToken);
theAccessToken.setExpiresIn(240);
}

if (keyVaultUri != null) {
keyVaultClient = new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret, managedIdentity,
disableChallengeResourceVerification);
theAccessToken, disableChallengeResourceVerification);
} else {
keyVaultClient = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void testGetAliasWithCertificateInfoWith1Page() {

utilities.when(() -> HttpUtil.get(notNull(), anyMap())).thenReturn(certificateListResultString);

KeyVaultClient keyVaultClient = new KeyVaultClient(KEY_VAULT_TEST_URI_GLOBAL, null);
KeyVaultClient keyVaultClient = new KeyVaultClient(KEY_VAULT_TEST_URI_GLOBAL, (String) null);
List<String> result = keyVaultClient.getAliases();

assertEquals(result.size(), 1);
Expand Down Expand Up @@ -101,7 +101,7 @@ public void testGetAliasWithCertificateInfoWith2Pages() {
utilities.when(() -> HttpUtil.get(eq("fakeNextLint"), anyMap()))
.thenReturn(certificateListResultStringNext);

KeyVaultClient keyVaultClient = new KeyVaultClient(KEY_VAULT_TEST_URI_GLOBAL, null);
KeyVaultClient keyVaultClient = new KeyVaultClient(KEY_VAULT_TEST_URI_GLOBAL, (String) null);
List<String> result = keyVaultClient.getAliases();

assertEquals(result.size(), 3);
Expand Down Expand Up @@ -138,7 +138,7 @@ private KeyVaultClient getKeyVaultClient() {
boolean disableChallengeResourceVerification
= Boolean.parseBoolean(System.getProperty("azure.keyvault.disable-challenge-resource-verification"));

return new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret, null,
return new KeyVaultClient(keyVaultUri, tenantId, clientId, clientSecret, null, null,
disableChallengeResourceVerification);
}

Expand Down
Loading