Skip to content

Commit

Permalink
Add managed identity live tests in new e2e module (#6833)
Browse files Browse the repository at this point in the history
* Add e2e module

* Add managed identity e2e test

* Add e2e module to pom.client.xml

* Try to fix assume

* Work around global configuration issue

* Remove pfx

* Fix configuration usage

* Fix dependency version tag

* Fix dependency version script

* Fix again

* Skip key vault tests when env var is missing

* Check key vault everywhere
  • Loading branch information
jianghaolu authored Dec 14, 2019
1 parent 7619e96 commit bd9c58b
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 2 deletions.
1 change: 1 addition & 0 deletions eng/versioning/version_client.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ com.azure:azure-storage-common;12.1.0;12.2.0-beta.1
com.azure:azure-storage-file-share;12.0.0;12.1.0-beta.1
com.azure:azure-storage-file-datalake;12.0.0-beta.7;12.0.0-beta.8
com.azure:azure-storage-queue;12.1.0;12.2.0-beta.1
com.azure:azure-e2e;1.0.0-beta.1;1.0.0-beta.1
1 change: 1 addition & 0 deletions pom.client.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1236,5 +1236,6 @@
<module>sdk/storage/azure-storage-file-share</module>
<module>sdk/storage/azure-storage-file-datalake</module>
<module>sdk/storage/azure-storage-queue</module>
<module>sdk/e2e</module>
</modules>
</project>
78 changes: 78 additions & 0 deletions sdk/e2e/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.azure</groupId>
<artifactId>azure-e2e</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:azure-e2e;current} -->

<name>Microsoft Azure client library end to end tests and samples</name>
<description>This module contains end to end tests and samples for Microsoft Azure client libraries.</description>
<url>https://github.com/Azure/azure-sdk-for-java</url>

<parent>
<groupId>com.azure</groupId>
<artifactId>azure-client-sdk-parent</artifactId>
<version>1.7.0</version> <!-- {x-version-update;com.azure:azure-client-sdk-parent;current} -->
<relativePath>../../pom.client.xml</relativePath>
</parent>

<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core</artifactId>
<version>1.2.0-beta.1</version> <!-- {x-version-update;com.azure:azure-core;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core-http-netty</artifactId>
<version>1.2.0-beta.1</version> <!-- {x-version-update;com.azure:azure-core-http-netty;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.1.0-beta.1</version> <!-- {x-version-update;com.azure:azure-identity;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-keys</artifactId>
<version>4.1.0-beta.1</version> <!-- {x-version-update;com.azure:azure-security-keyvault-keys;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-secrets</artifactId>
<version>4.1.0-beta.1</version> <!-- {x-version-update;com.azure:azure-security-keyvault-secrets;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-certificates</artifactId>
<version>4.0.0-beta.7</version> <!-- {x-version-update;com.azure:azure-security-keyvault-certificates;current} -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version> <!-- {x-version-update;org.slf4j:slf4j-api;external_dependency} -->
</dependency>

<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core-test</artifactId>
<version>1.1.0-beta.1</version> <!-- {x-version-update;com.azure:azure-core-test;current} -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13-beta-3</version> <!-- {x-version-update;junit:junit;external_dependency} -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.3.0.RELEASE</version> <!-- {x-version-update;io.projectreactor:reactor-test;external_dependency} -->
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.endtoend.identity;

import com.azure.core.credential.TokenRequestContext;
import com.azure.core.util.Configuration;
import com.azure.identity.ManagedIdentityCredential;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.identity.implementation.IdentityClient;
import com.azure.identity.implementation.IdentityClientBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
import org.junit.Assert;
import org.junit.Test;
import reactor.test.StepVerifier;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class ManagedIdentityCredentialLiveTest {
private static final String AZURE_VAULT_URL = "AZURE_VAULT_URL";
private static final String VAULT_SECRET_NAME = "secret";
private static final Configuration CONFIGURATION = Configuration.getGlobalConfiguration().clone();

@Test
public void testMSIEndpointWithSystemAssigned() throws Exception {
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_MSI_ENDPOINT));
org.junit.Assume.assumeTrue(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID) == null);
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

IdentityClient client = new IdentityClientBuilder().build();
StepVerifier.create(client.authenticateToManagedIdentityEndpoint(
CONFIGURATION.get(Configuration.PROPERTY_MSI_ENDPOINT),
CONFIGURATION.get(Configuration.PROPERTY_MSI_SECRET),
new TokenRequestContext().addScopes("https://management.azure.com/.default")))
.expectNextMatches(accessToken -> accessToken != null && accessToken.getToken() != null)
.verifyComplete();
}

@Test
public void testMSIEndpointWithSystemAssignedAccessKeyVault() throws Exception {
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_MSI_ENDPOINT));
org.junit.Assume.assumeTrue(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID) == null);
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder().build();

SecretClient client = new SecretClientBuilder()
.credential(credential)
.vaultUrl(CONFIGURATION.get(AZURE_VAULT_URL))
.buildClient();

KeyVaultSecret secret = client.getSecret(VAULT_SECRET_NAME);
Assert.assertNotNull(secret);
Assert.assertEquals(VAULT_SECRET_NAME, secret.getName());
Assert.assertNotNull(secret.getValue());
}

@Test
public void testMSIEndpointWithUserAssigned() throws Exception {
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_MSI_ENDPOINT));
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID));
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

IdentityClient client = new IdentityClientBuilder()
.clientId(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID))
.build();
StepVerifier.create(client.authenticateToManagedIdentityEndpoint(
CONFIGURATION.get(Configuration.PROPERTY_MSI_ENDPOINT),
CONFIGURATION.get(Configuration.PROPERTY_MSI_SECRET),
new TokenRequestContext().addScopes("https://management.azure.com/.default")))
.expectNextMatches(accessToken -> accessToken != null && accessToken.getToken() != null)
.verifyComplete();
}

@Test
public void testMSIEndpointWithUserAssignedAccessKeyVault() throws Exception {
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_MSI_ENDPOINT));
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID));
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder()
.clientId(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID))
.build();

SecretClient client = new SecretClientBuilder()
.credential(credential)
.vaultUrl(CONFIGURATION.get(AZURE_VAULT_URL))
.buildClient();

KeyVaultSecret secret = client.getSecret(VAULT_SECRET_NAME);
Assert.assertNotNull(secret);
Assert.assertEquals(VAULT_SECRET_NAME, secret.getName());
Assert.assertNotNull(secret.getValue());
}

@Test
public void testIMDSEndpointWithSystemAssigned() throws Exception {
org.junit.Assume.assumeTrue(checkIMDSAvailable());
org.junit.Assume.assumeTrue(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID) == null);
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

IdentityClient client = new IdentityClientBuilder().build();
StepVerifier.create(client.authenticateToIMDSEndpoint(
new TokenRequestContext().addScopes("https://management.azure.com/.default")))
.expectNextMatches(accessToken -> accessToken != null && accessToken.getToken() != null)
.verifyComplete();
}

@Test
public void testIMDSEndpointWithSystemAssignedAccessKeyVault() throws Exception {
org.junit.Assume.assumeTrue(checkIMDSAvailable());
org.junit.Assume.assumeTrue(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID) == null);
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder().build();

SecretClient client = new SecretClientBuilder()
.credential(credential)
.vaultUrl(CONFIGURATION.get(AZURE_VAULT_URL))
.buildClient();

KeyVaultSecret secret = client.getSecret(VAULT_SECRET_NAME);
Assert.assertNotNull(secret);
Assert.assertEquals(VAULT_SECRET_NAME, secret.getName());
Assert.assertNotNull(secret.getValue());
}

@Test
public void testIMDSEndpointWithUserAssigned() throws Exception {
org.junit.Assume.assumeTrue(checkIMDSAvailable());
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID));
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

IdentityClient client = new IdentityClientBuilder()
.clientId(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID))
.build();
StepVerifier.create(client.authenticateToIMDSEndpoint(
new TokenRequestContext().addScopes("https://management.azure.com/.default")))
.expectNextMatches(accessToken -> accessToken != null && accessToken.getToken() != null)
.verifyComplete();
}

@Test
public void testIMDSEndpointWithUserAssignedAccessKeyVault() throws Exception {
org.junit.Assume.assumeTrue(checkIMDSAvailable());
org.junit.Assume.assumeNotNull(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID));
org.junit.Assume.assumeNotNull(CONFIGURATION.get(AZURE_VAULT_URL));

ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder()
.clientId(CONFIGURATION.get(Configuration.PROPERTY_AZURE_CLIENT_ID))
.build();

SecretClient client = new SecretClientBuilder()
.credential(credential)
.vaultUrl(CONFIGURATION.get(AZURE_VAULT_URL))
.buildClient();

KeyVaultSecret secret = client.getSecret(VAULT_SECRET_NAME);
Assert.assertNotNull(secret);
Assert.assertEquals(VAULT_SECRET_NAME, secret.getName());
Assert.assertNotNull(secret.getValue());
}

private boolean checkIMDSAvailable() {
StringBuilder payload = new StringBuilder();

try {
payload.append("api-version=");
payload.append(URLEncoder.encode("2018-02-01", "UTF-8"));
} catch (IOException exception) {
return false;
}

HttpURLConnection connection = null;

try {
URL url = new URL(String.format("http://169.254.169.254/metadata/identity/oauth2/token?%s",
payload.toString()));

connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(500);
connection.connect();
return true;
} catch (Exception e) {
return false;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class AppServiceMsiCredential {
* @param identityClient The identity client to acquire a token with.
*/
AppServiceMsiCredential(String clientId, IdentityClient identityClient) {
Configuration configuration = Configuration.getGlobalConfiguration();
Configuration configuration = Configuration.getGlobalConfiguration().clone();
this.msiEndpoint = configuration.get(Configuration.PROPERTY_MSI_ENDPOINT);
this.msiSecret = configuration.get(Configuration.PROPERTY_MSI_SECRET);
this.identityClient = identityClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public final class ManagedIdentityCredential implements TokenCredential {
.clientId(clientId)
.identityClientOptions(identityClientOptions)
.build();
Configuration configuration = Configuration.getGlobalConfiguration();
Configuration configuration = Configuration.getGlobalConfiguration().clone();
if (configuration.contains(Configuration.PROPERTY_MSI_ENDPOINT)) {
appServiceMSICredential = new AppServiceMsiCredential(clientId, identityClient);
virtualMachineMSICredential = null;
Expand Down

0 comments on commit bd9c58b

Please sign in to comment.