Skip to content
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

Add managed identity live tests in new e2e module #6833

Merged
merged 12 commits into from
Dec 14, 2019
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: sort these alphabetically

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>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

</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;dependency} -->
</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;dependency} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.1.0-beta.1</version> <!-- {x-version-update;com.azure:azure-identity;dependency} -->
</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;dependency} -->
</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;dependency} -->
</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;dependency} -->
</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;io.projectreactor:reactor-test;external_dependency} -->
<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,187 @@
package com.azure.e2e.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);

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);

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));

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));

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);

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);

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));

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));

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