From 593fe8e2b11eca2e3d9671ee9f19803c6f2771e7 Mon Sep 17 00:00:00 2001 From: Pallavi Taneja Date: Mon, 7 Jun 2021 13:21:08 -0700 Subject: [PATCH 1/2] Add support for national clouds --- .../README.md | 66 ++++-- .../ContainerRegistryClientBuilder.java | 12 +- .../containers/containerregistry/Utils.java | 30 ++- .../NationalCloudSample.java | 29 +++ .../containerregistry/ReadmeSamples.java | 22 ++ ...ntainerRegistryClientIntegrationTests.java | 22 ++ .../containerregistry/TestUtils.java | 4 + ...ationTests.authenticationScopeTest[1].json | 207 ++++++++++++++++++ 8 files changed, 352 insertions(+), 40 deletions(-) create mode 100644 sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/NationalCloudSample.java create mode 100644 sdk/containerregistry/azure-containers-containerregistry/src/test/resources/session-records/ContainerRegistryClientIntegrationTests.authenticationScopeTest[1].json diff --git a/sdk/containerregistry/azure-containers-containerregistry/README.md b/sdk/containerregistry/azure-containers-containerregistry/README.md index 772bc5bd0c182..825eebdd751ac 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/README.md +++ b/sdk/containerregistry/azure-containers-containerregistry/README.md @@ -37,7 +37,7 @@ The [Azure Identity library][identity] provides easy Azure Active Directory supp Note all the below samples assume you have an endpoint, which is the URL including the name of the login server and the `https://` prefix. More information at [Azure Container Registry portal][container_registry_create_portal] - + ```Java DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); ContainerRegistryClient client = new ContainerRegistryClientBuilder() @@ -46,7 +46,7 @@ ContainerRegistryClient client = new ContainerRegistryClientBuilder() .buildClient(); ``` - + ```Java DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); ContainerRegistryAsyncClient client = new ContainerRegistryClientBuilder() @@ -57,20 +57,43 @@ ContainerRegistryAsyncClient client = new ContainerRegistryClientBuilder() For more information on using AAD with Azure Container Registry, please see the service's [Authentication Overview](https://docs.microsoft.com/azure/container-registry/container-registry-authentication). +#### National Clouds +To authenticate with a registry in a [National Cloud](https://docs.microsoft.com/azure/active-directory/develop/authentication-national-cloud), you will need to make the following additions to your client configuration: +- Set the authorityHost in the credential builder. +- Set the authenticationScope in ContainerRegistryClientBuilder. + + +```Java +AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE_US_GOVERNMENT); +TokenCredential credentials = new DefaultAzureCredentialBuilder() + .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint()) + .build(); + +ContainerRegistryClient containerRegistryClient = new ContainerRegistryClientBuilder() + .endpoint(getEndpoint()) + .credential(credentials) + .authenticationScope(getAuthenticationScope()) + .buildClient(); + +containerRegistryClient + .listRepositoryNames() + .forEach(name -> System.out.println(name)); +``` + ### Anonymous access support If the builder is instantiated without any credentials, the SDK creates the service client for the anonymous pull mode. The user must use this setting on a registry that has been enabled for anonymous pull. In this mode, the user can only call listRepositoryNames method and its overload. All the other calls will fail. For more information please read [Anonymous Pull Access](https://docs.microsoft.com/azure/container-registry/container-registry-faq#how-do-i-enable-anonymous-pull-access) - + ```Java ContainerRegistryClient client = new ContainerRegistryClientBuilder() .endpoint(endpoint) .buildClient(); ``` - + ```Java ContainerRegistryAsyncClient client = new ContainerRegistryClientBuilder() .endpoint(endpoint) @@ -105,7 +128,7 @@ For more information please see [Container Registry Concepts](https://docs.micro Iterate through the collection of repositories in the registry. - + ```Java DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); ContainerRegistryClient client = new ContainerRegistryClientBuilder() @@ -118,7 +141,7 @@ client.listRepositoryNames().forEach(repository -> System.out.println(repository ### List tags with anonymous access - + ```Java ContainerRegistryClient anonymousClient = new ContainerRegistryClientBuilder() .endpoint(endpoint) @@ -136,7 +159,7 @@ for (ArtifactTagProperties tag : tags) { ### Set artifact properties - + ```Java TokenCredential defaultCredential = new DefaultAzureCredentialBuilder().build(); @@ -156,7 +179,7 @@ image.updateTagProperties( ### Delete Images - + ```Java TokenCredential defaultCredential = new DefaultAzureCredentialBuilder().build(); @@ -190,7 +213,7 @@ for (String repositoryName : client.listRepositoryNames()) { ``` ### Delete repository with anonymous access throws - + ```Java final String endpoint = getEndpoint(); final String repositoryName = getRepositoryName(); @@ -212,20 +235,19 @@ try { All container registry service operations will throw a [HttpResponseException][HttpResponseException] on failure. - + ```Java -public void getPropertiesThrows() { - DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); - ContainerRepository containerRepository = new ContainerRegistryClientBuilder() - .endpoint(endpoint) - .credential(credential) - .buildClient() - .getRepository(repositoryName); - try { - containerRepository.getProperties(); - } catch (HttpResponseException exception) { - // Do something with the exception. - } +DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); +ContainerRepository containerRepository = new ContainerRegistryClientBuilder() + .endpoint(endpoint) + .credential(credential) + .buildClient() + .getRepository(repositoryName); +try { + containerRepository.getProperties(); +} catch (HttpResponseException exception) { + // Do something with the exception. +} ``` ## Next steps diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/ContainerRegistryClientBuilder.java b/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/ContainerRegistryClientBuilder.java index 92d0f42d3e0e9..81cf63f5f781e 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/ContainerRegistryClientBuilder.java +++ b/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/ContainerRegistryClientBuilder.java @@ -107,14 +107,10 @@ public ContainerRegistryClientBuilder endpoint(String endpoint) { /** * Sets the authentication scope to be used for getting AAD credentials. * - *

NOTE - This is a temporary property that is added into the system until the service - * exposes this directly via the challenge based auth scheme. - * If this property is not provided then by default Azure public scope is used for authentication. - *

- * - *

- * Example:- For Azure public cloud this value is same as AzureEnvironment.Azure.managementEndpoint(). - * For more information - https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities#azure-resource-manager + *

To connect to a different cloud, set this value to "<resource-id>/.default", + * where <resource-id> is one of the Resource IDs listed at + * https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/services-support-managed-identities#azure-resource-manager. + * For example, to connect to the Azure Germany cloud, {@code authenticationScope} is set to "https://management.microsoftazure.de/.default". *

* * @param authenticationScope ARM management scope associated with the given registry. diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/Utils.java b/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/Utils.java index 7d82d0fa78329..2aa204665f78b 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/Utils.java +++ b/sdk/containerregistry/azure-containers-containerregistry/src/main/java/com/azure/containers/containerregistry/Utils.java @@ -132,27 +132,37 @@ static PagedResponse getPagedResponseWithContinuationToken(PagedRespon * @return The exception returned by the public methods. */ static Throwable mapException(Throwable exception) { - if (!(exception instanceof AcrErrorsException)) { - return exception; + AcrErrorsException acrException = null; + + if (exception instanceof AcrErrorsException) { + acrException = ((AcrErrorsException) exception); + } else if (exception instanceof RuntimeException) { + RuntimeException runtimeException = (RuntimeException) exception; + Throwable throwable = runtimeException.getCause(); + if (throwable instanceof AcrErrorsException) { + acrException = (AcrErrorsException) throwable; + } } - final AcrErrorsException errorsException = ((AcrErrorsException) exception); - final HttpResponse errorHttpResponse = errorsException.getResponse(); + if (acrException == null) { + return exception; + } + final HttpResponse errorHttpResponse = acrException.getResponse(); final int statusCode = errorHttpResponse.getStatusCode(); - final String errorDetail = errorsException.getMessage(); + final String errorDetail = acrException.getMessage(); switch (statusCode) { case 401: - return new ClientAuthenticationException(errorDetail, errorsException.getResponse(), exception); + return new ClientAuthenticationException(errorDetail, acrException.getResponse(), exception); case 404: - return new ResourceNotFoundException(errorDetail, errorsException.getResponse(), exception); + return new ResourceNotFoundException(errorDetail, acrException.getResponse(), exception); case 409: - return new ResourceExistsException(errorDetail, errorsException.getResponse(), exception); + return new ResourceExistsException(errorDetail, acrException.getResponse(), exception); case 412: - return new ResourceModifiedException(errorDetail, errorsException.getResponse(), exception); + return new ResourceModifiedException(errorDetail, acrException.getResponse(), exception); default: - return new HttpResponseException(errorDetail, errorsException.getResponse(), exception); + return new HttpResponseException(errorDetail, acrException.getResponse(), exception); } } diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/NationalCloudSample.java b/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/NationalCloudSample.java new file mode 100644 index 0000000000000..753ad7f74dadf --- /dev/null +++ b/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/NationalCloudSample.java @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.containers.containerregistry; + +import com.azure.core.credential.TokenCredential; +import com.azure.core.management.AzureEnvironment; +import com.azure.core.management.profile.AzureProfile; +import com.azure.identity.DefaultAzureCredentialBuilder; + +public class NationalCloudSample { + + public static void main(String[] args) { + final String endpoint = "endpoint"; + final String authenticationScope = "scope"; + AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE_US_GOVERNMENT); + TokenCredential credentials = new DefaultAzureCredentialBuilder() + .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint()) + .build(); + + ContainerRegistryAsyncClient asyncClient = new ContainerRegistryClientBuilder() + .endpoint(endpoint) + .credential(credentials) + .authenticationScope(authenticationScope) + .buildAsyncClient(); + + asyncClient.listRepositoryNames().subscribe(name -> System.out.println(name)); + } +} diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java b/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java index 507a7e0434f19..48d76c0482f11 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java +++ b/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java @@ -9,6 +9,8 @@ import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.HttpResponseException; import com.azure.core.http.rest.PagedIterable; +import com.azure.core.management.AzureEnvironment; +import com.azure.core.management.profile.AzureProfile; import com.azure.core.util.Context; import com.azure.identity.DefaultAzureCredential; import com.azure.identity.DefaultAzureCredentialBuilder; @@ -177,5 +179,25 @@ private static String getTagName() { return null; } + public void authenticationScopeSample() { + AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE_US_GOVERNMENT); + TokenCredential credentials = new DefaultAzureCredentialBuilder() + .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint()) + .build(); + + ContainerRegistryClient containerRegistryClient = new ContainerRegistryClientBuilder() + .endpoint(getEndpoint()) + .credential(credentials) + .authenticationScope(getAuthenticationScope()) + .buildClient(); + + containerRegistryClient + .listRepositoryNames() + .forEach(name -> System.out.println(name)); + } + + private static String getAuthenticationScope() { + return null; + } } diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/ContainerRegistryClientIntegrationTests.java b/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/ContainerRegistryClientIntegrationTests.java index 0c5b67d1384be..ada256e3fdd40 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/ContainerRegistryClientIntegrationTests.java +++ b/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/ContainerRegistryClientIntegrationTests.java @@ -4,6 +4,7 @@ package com.azure.containers.containerregistry; +import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.http.HttpClient; import com.azure.core.test.TestMode; import com.azure.core.test.implementation.ImplUtils; @@ -19,6 +20,8 @@ import java.util.stream.Collectors; import static com.azure.containers.containerregistry.TestUtils.ALPINE_REPOSITORY_NAME; +import static com.azure.containers.containerregistry.TestUtils.AZURE_GLOBAL_AUTHENTICATION_SCOPE; +import static com.azure.containers.containerregistry.TestUtils.AZURE_GOV_AUTHENTICATION_SCOPE; import static com.azure.containers.containerregistry.TestUtils.DISPLAY_NAME_WITH_ARGUMENTS; import static com.azure.containers.containerregistry.TestUtils.HELLO_WORLD_REPOSITORY_NAME; import static com.azure.containers.containerregistry.TestUtils.LATEST_TAG_NAME; @@ -168,5 +171,24 @@ public void convenienceProperties(HttpClient httpClient) { assertEquals(registryEndpoint, registryAsyncClient.getEndpoint()); assertEquals(registryEndpoint, registryClient.getEndpoint()); } + + @ParameterizedTest(name = DISPLAY_NAME_WITH_ARGUMENTS) + @MethodSource("getHttpClients") + public void authenticationScopeTest(HttpClient httpClient) { + ContainerRegistryClient registryClient = getContainerRegistryBuilder(httpClient) + .authenticationScope(AZURE_GLOBAL_AUTHENTICATION_SCOPE) + .buildClient(); + + List repositories = registryClient.listRepositoryNames().stream().collect(Collectors.toList()); + validateRepositories(repositories); + + if (getTestMode() != TestMode.PLAYBACK) { + // Now doing the same should fail with the separate registryClient; + ContainerRegistryClient throwableRegistryClient = getContainerRegistryBuilder(httpClient) + .authenticationScope(AZURE_GOV_AUTHENTICATION_SCOPE) + .buildClient(); + assertThrows(ClientAuthenticationException.class, () -> throwableRegistryClient.listRepositoryNames().stream().collect(Collectors.toList())); + } + } } diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/TestUtils.java b/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/TestUtils.java index f346adeb608ca..a0097dad8c80e 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/TestUtils.java +++ b/sdk/containerregistry/azure-containers-containerregistry/src/test/java/com/azure/containers/containerregistry/TestUtils.java @@ -59,6 +59,8 @@ public class TestUtils { public static final String QUARANTINE_STATE; public static final String QUARANTINE_DETAILS; public static final int HTTP_STATUS_CODE_202; + public static final String AZURE_GLOBAL_AUTHENTICATION_SCOPE; + public static final String AZURE_GOV_AUTHENTICATION_SCOPE; static { CONFIGURATION = Configuration.getGlobalConfiguration().clone(); @@ -95,6 +97,8 @@ public class TestUtils { QUARANTINE_STATE = "quarantine_state"; QUARANTINE_DETAILS = "quaratine_details"; HTTP_STATUS_CODE_202 = 202; + AZURE_GLOBAL_AUTHENTICATION_SCOPE = "https://management.azure.com/.default"; + AZURE_GOV_AUTHENTICATION_SCOPE = "https://management.usgovcloudapi.net/.default"; } static class FakeCredentials implements TokenCredential { diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/test/resources/session-records/ContainerRegistryClientIntegrationTests.authenticationScopeTest[1].json b/sdk/containerregistry/azure-containers-containerregistry/src/test/resources/session-records/ContainerRegistryClientIntegrationTests.authenticationScopeTest[1].json new file mode 100644 index 0000000000000..6e82c1c74efe8 --- /dev/null +++ b/sdk/containerregistry/azure-containers-containerregistry/src/test/resources/session-records/ContainerRegistryClientIntegrationTests.authenticationScopeTest[1].json @@ -0,0 +1,207 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://REDACTED.azurecr.io/oauth2/exchange", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "aef2d4b6-76f8-49de-9fbe-689ece4f356b", + "Content-Type" : "application/x-www-form-urlencoded" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "X-Ms-Correlation-Request-Id" : "bf1b5098-1805-42a8-9f5b-ea5dcbc3b3a7", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains", + "Server" : "openresty", + "Connection" : "keep-alive", + "x-ms-ratelimit-remaining-calls-per-second" : "166.65", + "retry-after" : "0", + "StatusCode" : "200", + "Body" : "{\"refresh_token\":\"REDACTED\"}", + "Date" : "Mon, 07 Jun 2021 21:06:47 GMT", + "Content-Type" : "application/json; charset=utf-8" + }, + "Exception" : null + }, { + "Method" : "POST", + "Uri" : "https://REDACTED.azurecr.io/oauth2/token", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "f36e39cc-0ce2-4d9a-b3cf-b7d97f884051", + "Content-Type" : "application/x-www-form-urlencoded" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "X-Ms-Correlation-Request-Id" : "d4e35c2d-a174-4dbb-87b9-54d7645be1d7", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains", + "Server" : "openresty", + "Connection" : "keep-alive", + "x-ms-ratelimit-remaining-calls-per-second" : "166.616667", + "retry-after" : "0", + "StatusCode" : "200", + "Body" : "{\"access_token\":\"REDACTED\"}", + "Date" : "Mon, 07 Jun 2021 21:06:47 GMT", + "Content-Type" : "application/json; charset=utf-8" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.azurecr.io/acr/v1/_catalog", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "dea14e3a-181a-426f-a252-fbeec0e2b129" + }, + "Response" : { + "content-length" : "82", + "Server" : "openresty", + "X-Content-Type-Options" : "nosniff", + "Connection" : "keep-alive", + "retry-after" : "0", + "StatusCode" : "200", + "Date" : "Mon, 07 Jun 2021 21:06:48 GMT", + "Docker-Distribution-Api-Version" : "registry/2.0", + "X-Ms-Correlation-Request-Id" : "dd7e3089-dc8f-4c58-967e-17d78de9236e", + "Access-Control-Expose-Headers" : "Docker-Content-Digest,WWW-Authenticate,Link,X-Ms-Correlation-Request-Id", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains,max-age=31536000; includeSubDomains", + "Body" : "{\"repositories\":[\"library/alpine\",\"library/hello-seattle\",\"library/hello-world\"]}\n", + "Content-Type" : "application/json; charset=utf-8" + }, + "Exception" : null + }, { + "Method" : "POST", + "Uri" : "https://REDACTED.azurecr.io/oauth2/exchange", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "a22ee2cf-b7a6-4ed9-a87f-fb040fd88af6", + "Content-Type" : "application/x-www-form-urlencoded" + }, + "Response" : { + "X-Ms-Correlation-Request-Id" : "e45fea56-74ff-4cf2-9e1e-392bda4c0954", + "content-length" : "78", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains", + "Server" : "openresty", + "Connection" : "keep-alive", + "x-ms-ratelimit-remaining-calls-per-second" : "166.633333", + "retry-after" : "0", + "StatusCode" : "401", + "Body" : "{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}", + "Date" : "Mon, 07 Jun 2021 21:06:48 GMT", + "Content-Type" : "application/json" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.azurecr.io/acr/v1/_catalog", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "8e977ca5-161d-4c07-b6c9-ad458c1711c9" + }, + "Response" : null, + "Exception" : { + "ClassName" : "com.azure.containers.containerregistry.implementation.models.AcrErrorsException", + "ErrorMessage" : "Status code 401, \"{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}\"" + } + }, { + "Method" : "POST", + "Uri" : "https://REDACTED.azurecr.io/oauth2/exchange", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "86009d73-bf8c-439a-9d64-a1e18862584e", + "Content-Type" : "application/x-www-form-urlencoded" + }, + "Response" : { + "X-Ms-Correlation-Request-Id" : "2d015054-4fb7-453d-ba22-6c2d527e8370", + "content-length" : "78", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains", + "Server" : "openresty", + "Connection" : "keep-alive", + "x-ms-ratelimit-remaining-calls-per-second" : "166.616667", + "retry-after" : "0", + "StatusCode" : "401", + "Body" : "{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}", + "Date" : "Mon, 07 Jun 2021 21:07:18 GMT", + "Content-Type" : "application/json" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.azurecr.io/acr/v1/_catalog", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "8e977ca5-161d-4c07-b6c9-ad458c1711c9" + }, + "Response" : null, + "Exception" : { + "ClassName" : "com.azure.containers.containerregistry.implementation.models.AcrErrorsException", + "ErrorMessage" : "Status code 401, \"{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}\"" + } + }, { + "Method" : "POST", + "Uri" : "https://REDACTED.azurecr.io/oauth2/exchange", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "a9c438e4-027d-48b6-b1e9-11855de5de94", + "Content-Type" : "application/x-www-form-urlencoded" + }, + "Response" : { + "X-Ms-Correlation-Request-Id" : "ba129c0b-6d7b-4396-9350-d2c03073cdf4", + "content-length" : "78", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains", + "Server" : "openresty", + "Connection" : "keep-alive", + "x-ms-ratelimit-remaining-calls-per-second" : "166.633333", + "retry-after" : "0", + "StatusCode" : "401", + "Body" : "{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}", + "Date" : "Mon, 07 Jun 2021 21:07:48 GMT", + "Content-Type" : "application/json" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.azurecr.io/acr/v1/_catalog", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "8e977ca5-161d-4c07-b6c9-ad458c1711c9" + }, + "Response" : null, + "Exception" : { + "ClassName" : "com.azure.containers.containerregistry.implementation.models.AcrErrorsException", + "ErrorMessage" : "Status code 401, \"{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}\"" + } + }, { + "Method" : "POST", + "Uri" : "https://REDACTED.azurecr.io/oauth2/exchange", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "7c9fe4cf-9038-46d1-a58c-d0cb514e158e", + "Content-Type" : "application/x-www-form-urlencoded" + }, + "Response" : { + "X-Ms-Correlation-Request-Id" : "bd03fb3b-c853-47ad-857b-e6903c2a6631", + "content-length" : "78", + "Strict-Transport-Security" : "max-age=31536000; includeSubDomains", + "Server" : "openresty", + "Connection" : "keep-alive", + "x-ms-ratelimit-remaining-calls-per-second" : "166.633333", + "retry-after" : "0", + "StatusCode" : "401", + "Body" : "{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}", + "Date" : "Mon, 07 Jun 2021 21:08:18 GMT", + "Content-Type" : "application/json" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.azurecr.io/acr/v1/_catalog", + "Headers" : { + "User-Agent" : "azsdk-java-UnknownName/UnknownVersion (11.0.10; Windows 10; 10.0)", + "x-ms-client-request-id" : "8e977ca5-161d-4c07-b6c9-ad458c1711c9" + }, + "Response" : null, + "Exception" : { + "ClassName" : "com.azure.containers.containerregistry.implementation.models.AcrErrorsException", + "ErrorMessage" : "Status code 401, \"{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"retrieving permissions failed\"}]}\"" + } + } ], + "variables" : [ ] +} \ No newline at end of file From b39acc0bd2c2fef001d123c032a84a3205849129 Mon Sep 17 00:00:00 2001 From: Pallavi Taneja Date: Thu, 10 Jun 2021 09:56:23 -0700 Subject: [PATCH 2/2] update the national cloud sample --- .../azure-containers-containerregistry/README.md | 5 +++-- .../azure/containers/containerregistry/ReadmeSamples.java | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sdk/containerregistry/azure-containers-containerregistry/README.md b/sdk/containerregistry/azure-containers-containerregistry/README.md index 825eebdd751ac..e28005d2bcbe2 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/README.md +++ b/sdk/containerregistry/azure-containers-containerregistry/README.md @@ -62,17 +62,18 @@ To authenticate with a registry in a [National Cloud](https://docs.microsoft.com - Set the authorityHost in the credential builder. - Set the authenticationScope in ContainerRegistryClientBuilder. - + ```Java AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE_US_GOVERNMENT); TokenCredential credentials = new DefaultAzureCredentialBuilder() .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint()) .build(); +final String authenticationScope = "https://management.usgovcloudapi.net/.default"; ContainerRegistryClient containerRegistryClient = new ContainerRegistryClientBuilder() .endpoint(getEndpoint()) .credential(credentials) - .authenticationScope(getAuthenticationScope()) + .authenticationScope(authenticationScope) .buildClient(); containerRegistryClient diff --git a/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java b/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java index 48d76c0482f11..f3749c60e2dce 100644 --- a/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java +++ b/sdk/containerregistry/azure-containers-containerregistry/src/samples/java/com/azure/containers/containerregistry/ReadmeSamples.java @@ -185,19 +185,16 @@ public void authenticationScopeSample() { .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint()) .build(); + final String authenticationScope = "https://management.usgovcloudapi.net/.default"; ContainerRegistryClient containerRegistryClient = new ContainerRegistryClientBuilder() .endpoint(getEndpoint()) .credential(credentials) - .authenticationScope(getAuthenticationScope()) + .authenticationScope(authenticationScope) .buildClient(); containerRegistryClient .listRepositoryNames() .forEach(name -> System.out.println(name)); } - - private static String getAuthenticationScope() { - return null; - } }