Skip to content
Merged
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
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;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));
Copy link
Member

Choose a reason for hiding this comment

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

Why use fully qualifed instead of importing this?

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