diff --git a/src/Accounts/Authentication.Test/AuthenticatorsTest/AccessTokenAuthenticatorTests.cs b/src/Accounts/Authentication.Test/AuthenticatorsTest/AccessTokenAuthenticatorTests.cs
new file mode 100644
index 000000000000..318889ab2825
--- /dev/null
+++ b/src/Accounts/Authentication.Test/AuthenticatorsTest/AccessTokenAuthenticatorTests.cs
@@ -0,0 +1,181 @@
+// ----------------------------------------------------------------------------------
+//
+// Copyright Microsoft Corporation
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ----------------------------------------------------------------------------------
+
+using System;
+using System.Threading.Tasks;
+
+using Microsoft.Azure.Commands.Common.Authentication;
+using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
+using Microsoft.Azure.PowerShell.Authenticators;
+using Microsoft.WindowsAzure.Commands.ScenarioTest;
+
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Common.Authenticators.Test
+{
+ ///
+ /// Tests for .
+ /// Covers the bug reported in https://github.com/Azure/azure-powershell/issues/28028 where
+ /// Get-AzAccessToken -ResourceUrl "https://management.azure.com/" failed when signed in via
+ /// Connect-AzAccount -AccessToken, even though the stored ARM token is valid for that audience.
+ ///
+ public class AccessTokenAuthenticatorTests
+ {
+ private const string TestTenantId = "test-tenant-id";
+ private const string TestUserId = "testuser@contoso.com";
+ private const string FakeArmToken = "fake-arm-access-token";
+ private const string FakeGraphToken = "fake-graph-access-token";
+ private const string FakeKeyVaultToken = "fake-keyvault-access-token";
+
+ private readonly IAzureEnvironment _azureCloud = AzureEnvironment.PublicEnvironments["AzureCloud"];
+
+ public AccessTokenAuthenticatorTests(ITestOutputHelper output)
+ {
+ AzureSessionInitializer.InitializeAzureSession();
+ }
+
+ private AzureAccount CreateAccessTokenAccount()
+ {
+ var account = new AzureAccount
+ {
+ Id = TestUserId,
+ Type = AzureAccount.AccountType.AccessToken,
+ };
+ account.SetProperty(AzureAccount.Property.AccessToken, FakeArmToken);
+ account.SetProperty(AzureAccount.Property.GraphAccessToken, FakeGraphToken);
+ account.SetProperty(AzureAccount.Property.KeyVaultAccessToken, FakeKeyVaultToken);
+ return account;
+ }
+
+ private AccessTokenParameters CreateParameters(string resourceId, AzureAccount account = null)
+ {
+ return new AccessTokenParameters(
+ new InMemoryTokenCacheProvider(),
+ _azureCloud,
+ null,
+ TestTenantId,
+ resourceId,
+ account ?? CreateAccessTokenAccount());
+ }
+
+ ///
+ /// Verifies that the stored ARM access token is returned when the resource URL is
+ /// the legacy management endpoint (https://management.core.windows.net/).
+ /// This is the pre-existing working case.
+ ///
+ [Fact]
+ [Trait(Category.AcceptanceType, Category.CheckIn)]
+ public async Task ReturnsArmToken_WhenResourceIsManagementCoreWindowsNet()
+ {
+ var resourceId = "https://management.core.windows.net/";
+ var parameters = CreateParameters(resourceId);
+ var authenticator = new AccessTokenAuthenticator();
+
+ var token = await authenticator.Authenticate(parameters);
+
+ Assert.NotNull(token);
+ Assert.Equal(FakeArmToken, token.AccessToken);
+ Assert.Equal(TestUserId, token.UserId);
+ Assert.Equal(TestTenantId, token.TenantId);
+ }
+
+ ///
+ /// Verifies that the stored ARM access token is returned when the resource URL is
+ /// https://management.azure.com/ — the Azure Resource Manager endpoint URL.
+ /// This covers the bug in https://github.com/Azure/azure-powershell/issues/28028.
+ ///
+ [Fact]
+ [Trait(Category.AcceptanceType, Category.CheckIn)]
+ public async Task ReturnsArmToken_WhenResourceIsManagementAzureCom()
+ {
+ // This is the resource URL that previously caused the error:
+ // "[AccessTokenAuthenticator] failed to retrieve access token for resource 'https://management.azure.com/'"
+ var resourceId = _azureCloud.GetEndpoint(AzureEnvironment.Endpoint.ResourceManager);
+ Assert.Equal("https://management.azure.com/", resourceId, StringComparer.OrdinalIgnoreCase);
+
+ var parameters = CreateParameters(resourceId);
+ var authenticator = new AccessTokenAuthenticator();
+
+ var token = await authenticator.Authenticate(parameters);
+
+ Assert.NotNull(token);
+ Assert.Equal(FakeArmToken, token.AccessToken);
+ Assert.Equal(TestUserId, token.UserId);
+ Assert.Equal(TestTenantId, token.TenantId);
+ }
+
+ ///
+ /// Verifies that the KeyVault access token is returned when requesting the KeyVault resource.
+ ///
+ [Fact]
+ [Trait(Category.AcceptanceType, Category.CheckIn)]
+ public async Task ReturnsKeyVaultToken_WhenResourceIsKeyVaultEndpoint()
+ {
+ var resourceId = _azureCloud.GetEndpoint(AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId);
+ var parameters = CreateParameters(resourceId);
+ var authenticator = new AccessTokenAuthenticator();
+
+ var token = await authenticator.Authenticate(parameters);
+
+ Assert.NotNull(token);
+ Assert.Equal(FakeKeyVaultToken, token.AccessToken);
+ }
+
+ ///
+ /// Verifies that the AAD Graph access token is returned when requesting the Graph resource.
+ ///
+ [Fact]
+ [Trait(Category.AcceptanceType, Category.CheckIn)]
+ public async Task ReturnsGraphToken_WhenResourceIsGraphEndpoint()
+ {
+ var resourceId = _azureCloud.GetEndpoint(AzureEnvironment.Endpoint.GraphEndpointResourceId);
+ var parameters = CreateParameters(resourceId);
+ var authenticator = new AccessTokenAuthenticator();
+
+ var token = await authenticator.Authenticate(parameters);
+
+ Assert.NotNull(token);
+ Assert.Equal(FakeGraphToken, token.AccessToken);
+ }
+
+ ///
+ /// Verifies that an InvalidOperationException is thrown when requesting a resource
+ /// for which no token was provided at login time.
+ ///
+ [Fact]
+ [Trait(Category.AcceptanceType, Category.CheckIn)]
+ public async Task ThrowsInvalidOperationException_WhenResourceIsUnsupported()
+ {
+ var resourceId = "https://unsupported.resource.example.com/";
+ var parameters = CreateParameters(resourceId);
+ var authenticator = new AccessTokenAuthenticator();
+
+ await Assert.ThrowsAsync(() => authenticator.Authenticate(parameters));
+ }
+
+ ///
+ /// Verifies that CanAuthenticate returns true only for AccessTokenParameters.
+ ///
+ [Fact]
+ [Trait(Category.AcceptanceType, Category.CheckIn)]
+ public void CanAuthenticate_ReturnsTrueForAccessTokenParameters()
+ {
+ var parameters = CreateParameters("https://management.azure.com/");
+ var authenticator = new AccessTokenAuthenticator();
+
+ Assert.True(authenticator.CanAuthenticate(parameters));
+ }
+ }
+}
diff --git a/src/Accounts/Authenticators/AccessTokenAuthenticator.cs b/src/Accounts/Authenticators/AccessTokenAuthenticator.cs
index 5ba7c72b6f92..b2dcceb5ee1f 100644
--- a/src/Accounts/Authenticators/AccessTokenAuthenticator.cs
+++ b/src/Accounts/Authenticators/AccessTokenAuthenticator.cs
@@ -68,7 +68,8 @@ public override Task Authenticate(AuthenticationParameters paramet
else if ((resourceId.EqualsInsensitively(environment.ActiveDirectoryServiceEndpointResourceId) ||
resourceId.EqualsInsensitively(AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId) ||
resourceId.EqualsInsensitively(environment.GetEndpoint(environment.ActiveDirectoryServiceEndpointResourceId)) ||
- resourceId.EqualsInsensitively(environment.GetEndpoint(AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId)))
+ resourceId.EqualsInsensitively(environment.GetEndpoint(AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId)) ||
+ resourceId.EqualsInsensitively(environment.GetEndpoint(AzureEnvironment.Endpoint.ResourceManager)))
&& account.IsPropertySet(AzureAccount.Property.AccessToken))
{
TracingAdapter.Information($"{DateTime.Now:T} - [AccessTokenAuthenticator] Creating access token - Tenant: '{tenant}', ResourceId: '{resourceId}', UserId: '{account.Id}'");