Skip to content

Accounts OOB Release #27561

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

Closed
wants to merge 12 commits into from
Closed
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
2 changes: 2 additions & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@





10 changes: 5 additions & 5 deletions src/Accounts/Accounts.Test/AccessTokenCmdletTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

using Microsoft.Azure.Commands.Common.Authentication;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces;
using Microsoft.Azure.Commands.Common.Authentication.Models;
using Microsoft.Azure.Commands.Profile;
using Microsoft.Azure.Commands.Profile.Models;
Expand All @@ -28,6 +29,7 @@
using Moq;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;

Expand All @@ -49,7 +51,7 @@ public AccessTokenCmdletTests(ITestOutputHelper output)
{
TestExecutionHelpers.SetUpSessionAndProfile();
XunitTracingInterceptor.AddToContext(new XunitTracingInterceptor(output));

AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
var defaultContext = new AzureContext(
new AzureSubscription()
{
Expand Down Expand Up @@ -97,8 +99,7 @@ public void TestGetAccessTokenAsPlainText()
It.IsAny<SecureString>(),
It.IsAny<string>(),
It.IsAny<Action<string>>(),
It.IsAny<IAzureTokenCache>(),
It.IsAny<string>())).Returns(new MockAccessToken
It.IsAny<IDictionary<string, object>>())).Returns(new MockAccessToken
{
UserId = expected.UserId,
LoginType = LoginType.OrgId,
Expand Down Expand Up @@ -146,8 +147,7 @@ public void TestGetAccessTokenAsSecureString()
It.IsAny<SecureString>(),
It.IsAny<string>(),
It.IsAny<Action<string>>(),
It.IsAny<IAzureTokenCache>(),
It.IsAny<string>())).Returns(new MockAccessToken
It.IsAny<IDictionary<string, object>>())).Returns(new MockAccessToken
{
UserId = expected.UserId,
LoginType = LoginType.OrgId,
Expand Down
3 changes: 1 addition & 2 deletions src/Accounts/Accounts.Test/AutosaveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
using Xunit.Abstractions;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
using System;
using System.Security;
using Microsoft.Azure.Commands.Profile.Context;
using Microsoft.Azure.Commands.ScenarioTest;
using Microsoft.Azure.Commands.ResourceManager.Common;
Expand Down Expand Up @@ -57,7 +56,6 @@ private AzKeyStore SetMockedAzKeyStore()

void ResetState()
{

TestExecutionHelpers.SetUpSessionAndProfile();
ResourceManagerProfileProvider.InitializeResourceManagerProfile(true);
// prevent token acquisition
Expand All @@ -69,6 +67,7 @@ void ResetState()
PowerShellTokenCacheProvider tokenProvider = new InMemoryTokenCacheProvider();
AzureSession.Instance.RegisterComponent(PowerShellTokenCacheProvider.PowerShellTokenCacheProviderKey, () => tokenProvider, true);
AzureSession.Instance.RegisterComponent(AzKeyStore.Name, () => keyStore, true);
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion src/Accounts/Accounts.Test/AzureRMProfileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
using System.Management.Automation;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -176,6 +175,7 @@ public AzureRMProfileTests(ITestOutputHelper output)
{
TestExecutionHelpers.SetUpSessionAndProfile();
XunitTracingInterceptor.AddToContext(new XunitTracingInterceptor(output));
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
}

[Fact]
Expand Down
1 change: 1 addition & 0 deletions src/Accounts/Accounts.Test/AzureSessionTestInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public static void Initialize()
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => builder);
AzureSession.Instance.RegisterComponent(nameof(AzureCredentialFactory), () => new AzureCredentialFactory());
AzureSession.Instance.RegisterComponent(nameof(MsalAccessTokenAcquirerFactory), () => new MsalAccessTokenAcquirerFactory());
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
}

}
Expand Down
1 change: 1 addition & 0 deletions src/Accounts/Accounts.Test/ContextCmdletTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public ContextCmdletTests(ITestOutputHelper output)
string profilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), Resources.AzureDirectoryName);
azKeyStore = new AzKeyStore(profilePath, AzureSession.Instance.KeyStoreFile, true, storageMocker.Object);
AzureSession.Instance.RegisterComponent(AzKeyStore.Name, () => azKeyStore, true);
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
}

[Fact]
Expand Down
1 change: 1 addition & 0 deletions src/Accounts/Accounts.Test/EnvironmentCmdletTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public EnvironmentCmdletTests(ITestOutputHelper output)
XunitTracingInterceptor.AddToContext(new XunitTracingInterceptor(output));
dataStore = new MemoryDataStore();
AzureSession.Instance.DataStore = dataStore;
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
}

private void Cleanup()
Expand Down
5 changes: 5 additions & 0 deletions src/Accounts/Accounts.Test/ErrorResolutionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
// ----------------------------------------------------------------------------------

using Hyak.Common;

using Microsoft.Azure.Commands.Common.Authentication;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
using Microsoft.Azure.Commands.Profile.Errors;
using Microsoft.Azure.Commands.ScenarioTest;
using Microsoft.WindowsAzure.Commands.Common.Test.Mocks;
Expand Down Expand Up @@ -43,6 +46,7 @@ public TestHyakException(string message, CloudHttpRequestErrorInfo request, Clou
public void DoesNotThrowWithNullError()
{
TestExecutionHelpers.SetUpSessionAndProfile();
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
var cmdlet = new ResolveError();
var output = cmdlet.ExecuteCmdletInPipeline<AzureErrorRecord>("Resolve-Error");
Assert.True(output == null || output.Count == 0);
Expand Down Expand Up @@ -168,6 +172,7 @@ public void HandlesNullValuesInArmExceptions()
public void LastParameterFindsLastError()
{
TestExecutionHelpers.SetUpSessionAndProfile();
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
var mock = new MockCommandRuntime();
var cmdlet = new ResolveError { CommandRuntime = mock };
var message = "RuntimeErrorMessage";
Expand Down
1 change: 1 addition & 0 deletions src/Accounts/Accounts.Test/ProfileCmdletTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public ProfileCmdletTests(ITestOutputHelper output)
AzureSession.Instance.DataStore = dataStore;
commandRuntimeMock = new MockCommandRuntime();
AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory();
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
keyStore = SetMockedAzKeyStore();
}

Expand Down
4 changes: 2 additions & 2 deletions src/Accounts/Accounts.Test/SilentReAuthByTenantCmdletTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Azure.Commands.Common.Authentication.Factories;

namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
{
Expand Down Expand Up @@ -326,6 +324,8 @@ private void InitializeSession()
DefaultContext = defaultContext
};
cmdlet.profileClient = new RMProfileClient(profile);

AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
}

~SilentReAuthByTenantCmdletTest()
Expand Down
3 changes: 1 addition & 2 deletions src/Accounts/Accounts.Test/TenantCmdletMockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
using Microsoft.Azure.Commands.ScenarioTest;
using Microsoft.Azure.Commands.TestFx.Mocks;
using Microsoft.Azure.ServiceManagement.Common.Models;
using Microsoft.WindowsAzure.Commands.Common.Test.Mocks;
using Microsoft.WindowsAzure.Commands.ScenarioTest;
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using Moq;
Expand Down Expand Up @@ -55,7 +54,7 @@ public TenantCmdletMockTests(ITestOutputHelper output)
{
TestExecutionHelpers.SetUpSessionAndProfile();
XunitTracingInterceptor.AddToContext(new XunitTracingInterceptor(output));

AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory();
((MockTokenAuthenticationFactory)AzureSession.Instance.AuthenticationFactory).TokenProvider = (account, environment, tenant) =>
new MockAccessToken
Expand Down
5 changes: 3 additions & 2 deletions src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Microsoft.Azure.Commands.Common.Authentication;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Models;
using Microsoft.Azure.Commands.Common.Authentication.Config.Models;
using Microsoft.Azure.Commands.Common.Authentication.Factories;
Expand Down Expand Up @@ -517,8 +518,7 @@ public override void ExecuteCmdlet()
return;
}

IHttpOperationsFactory httpClientFactory = null;
AzureSession.Instance.TryGetComponent(HttpClientOperationsFactory.Name, out httpClientFactory);
AzureSession.Instance.TryGetComponent(HttpClientOperationsFactory.Name, out IHttpOperationsFactory httpClientFactory);

SetContextWithOverwritePrompt((localProfile, profileClient, name) =>
{
Expand Down Expand Up @@ -860,6 +860,7 @@ public void OnImport()
AzureSession.Instance.RegisterComponent(nameof(MsalAccessTokenAcquirerFactory), () => new MsalAccessTokenAcquirerFactory());
AzureSession.Instance.RegisterComponent<ISshCredentialFactory>(nameof(ISshCredentialFactory), () => new SshCredentialFactory());
AzureSession.Instance.RegisterComponent<IOutputSanitizer>(nameof(IOutputSanitizer), () => new OutputSanitizer());
AzureSession.Instance.RegisterComponent<AuthenticationTelemetry>(AuthenticationTelemetry.Name, () => new AuthenticationTelemetry());
#if DEBUG || TESTCOVERAGE
AzureSession.Instance.RegisterComponent<ITestCoverage>(nameof(ITestCoverage), () => new TestCoverage());
#endif
Expand Down
7 changes: 4 additions & 3 deletions src/Accounts/Accounts/Az.Accounts.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# Generated by: Microsoft Corporation
#
# Generated on: 26/03/2025
# Generated on: 4/14/2025
#

@{
Expand All @@ -12,7 +12,7 @@
# RootModule = ''

# Version number of this module.
ModuleVersion = '4.1.0'
ModuleVersion = '4.2.0'

# Supported PSEditions
CompatiblePSEditions = 'Core', 'Desktop'
Expand Down Expand Up @@ -146,7 +146,8 @@ PrivateData = @{
# IconUri = ''

# ReleaseNotes of this module
ReleaseNotes = '* Added AppConfiguration ResourceId and Suffix endpoints for Mooncake and USGov clouds to fix issue [#24219]'
ReleaseNotes = '* Fix token in auxiliary authentication header.
* Collected authentication method for telemetry in end process of cmdlet.'

# Prerelease string of this module
# Prerelease = ''
Expand Down
4 changes: 4 additions & 0 deletions src/Accounts/Accounts/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

## Upcoming Release

## Version 4.2.0
* Fix token in auxiliary authentication header.
* Collected authentication method for telemetry in end process of cmdlet.

## Version 4.1.0
* Added AppConfiguration ResourceId and Suffix endpoints for Mooncake and USGov clouds to fix issue [#24219]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ protected virtual void ModifyContext(Action<AzureRmProfile, RMProfileClient> con
{
var client = new RMProfileClient(profile)
{
WarningLog = (s) => WriteWarning(s)
WarningLog = (s) => WriteWarning(s),
CmdletContext = _cmdletContext
};
contextAction(profile.ToProfile(), client);
}
Expand Down
33 changes: 24 additions & 9 deletions src/Accounts/Accounts/CommonModule/ContextAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
using System.Management.Automation;
using Microsoft.Azure.Commands.Profile.Properties;
using Azure.Identity;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Extensions;
using Microsoft.Azure.Commands.Common.Authentication.Factories;

namespace Microsoft.Azure.Commands.Common
{
Expand Down Expand Up @@ -75,7 +78,7 @@ public void OnNewRequest(InvocationInfo invocationInfo, string correlationId, st
{
prependStep(UniqueId.Instance.SendAsync);
appendStep(new UserAgent(invocationInfo).SendAsync);
appendStep(this.SendHandler(GetDefaultContext(_provider, invocationInfo), AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId));
appendStep(this.SendHandler(GetDefaultContext(_provider, invocationInfo), AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId, new AzureCmdletContext(correlationId)));
}

internal void AddRequestUserAgentHandler(
Expand Down Expand Up @@ -118,7 +121,12 @@ internal void AddAuthorizeRequestHandler(
{
endpointResourceIdKey = endpointResourceIdKey ?? AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId;
var context = GetDefaultContext(_provider, invocationInfo);
return await AuthenticationHelper(context, endpointResourceIdKey, endpointSuffixKey, request, cancelToken, cancelAction, signal, next);
ICmdletContext cmdletContext = AzureCmdletContext.CmdletNone;
if (extensibleParameters.ContainsKey(AuthenticationFactory.CmdletContextParameterName))
{
cmdletContext = extensibleParameters[AuthenticationFactory.CmdletContextParameterName] as ICmdletContext;
}
return await AuthenticationHelper(context, endpointResourceIdKey, endpointSuffixKey, request, cancelToken, cancelAction, signal, next, cmdletContext);
});
}

Expand Down Expand Up @@ -193,9 +201,10 @@ public object GetParameterValue(string resourceId, string moduleName, Invocation
return string.Empty;
}

internal async Task<HttpResponseMessage> AuthenticationHelper(IAzureContext context, string endpointResourceIdKey, string endpointSuffixKey, HttpRequestMessage request, CancellationToken cancelToken, Action cancelAction, SignalDelegate signal, NextDelegate next, TokenAudienceConverterDelegate tokenAudienceConverter = null)
internal async Task<HttpResponseMessage> AuthenticationHelper(IAzureContext context, string endpointResourceIdKey, string endpointSuffixKey, HttpRequestMessage request, CancellationToken cancelToken, Action cancelAction, SignalDelegate signal, NextDelegate next, ICmdletContext cmdletContext, TokenAudienceConverterDelegate tokenAudienceConverter = null)
{
IAccessToken accessToken = await AuthorizeRequest(context, request, cancelToken, endpointResourceIdKey, endpointSuffixKey, tokenAudienceConverter);
var extensiableParameters = cmdletContext?.ToExtensibleParameters();
IAccessToken accessToken = await AuthorizeRequest(context, request, cancelToken, endpointResourceIdKey, endpointSuffixKey, tokenAudienceConverter, extensiableParameters);
using (var newRequest = await request.CloneWithContent(request.RequestUri, request.Method))
{
var response = await next(request, cancelToken, cancelAction, signal);
Expand Down Expand Up @@ -232,13 +241,14 @@ internal async Task<HttpResponseMessage> AuthenticationHelper(IAzureContext cont
/// </summary>
/// <param name="context"></param>
/// <param name="resourceId"></param>
/// <param name="cmdletContext"></param>
/// <returns></returns>
internal Func<HttpRequestMessage, CancellationToken, Action, SignalDelegate, NextDelegate, Task<HttpResponseMessage>> SendHandler(IAzureContext context, string resourceId)
internal Func<HttpRequestMessage, CancellationToken, Action, SignalDelegate, NextDelegate, Task<HttpResponseMessage>> SendHandler(IAzureContext context, string resourceId, ICmdletContext cmdletContext)
{
return async (request, cancelToken, cancelAction, signal, next) =>
{
PatchRequestUri(context, request);
return await AuthenticationHelper(context, resourceId, resourceId, request, cancelToken, cancelAction, signal, next);
return await AuthenticationHelper(context, resourceId, resourceId, request, cancelToken, cancelAction, signal, next, cmdletContext);
};
}

Expand All @@ -249,12 +259,12 @@ internal Func<HttpRequestMessage, CancellationToken, Action, SignalDelegate, Nex
/// <param name="endpointResourceIdKey"></param>
/// <param name="request"></param>
/// <param name="endpointSuffixKey"></param>
/// <param name="extensibleParamters"></param>
/// <param name="extensibleParameters"></param>
/// <param name="tokenAudienceConverter"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
internal async Task<IAccessToken> AuthorizeRequest(IAzureContext context, HttpRequestMessage request, CancellationToken cancellationToken, string endpointResourceIdKey,
string endpointSuffixKey, TokenAudienceConverterDelegate tokenAudienceConverter = null, IDictionary<string, object> extensibleParamters = null)
string endpointSuffixKey, TokenAudienceConverterDelegate tokenAudienceConverter = null, IDictionary<string, object> extensibleParameters = null)
{
if (context == null || context.Account == null || context.Environment == null)
{
Expand All @@ -269,7 +279,12 @@ internal async Task<IAccessToken> AuthorizeRequest(IAzureContext context, HttpRe
var tokenAudience = tokenAudienceConverter.Invoke(info.CurEnvEndpointResourceId, info.CurEnvEndpointSuffix, info.BaseEnvEndpointResourceId, info.BaseEnvEndpointSuffix, request.RequestUri);
endpointResourceIdKey = tokenAudience ?? endpointResourceIdKey;
}
var authToken = _authenticator.Authenticate(context.Account, context.Environment, context.Tenant.Id, null, "Never", null, endpointResourceIdKey);
var optionalParameters = new Dictionary<string, object>() { { AuthenticationFactory.ResourceIdParameterName, endpointResourceIdKey } };
if (extensibleParameters != null && extensibleParameters.ContainsKey(AuthenticationFactory.CmdletContextParameterName))
{
optionalParameters.Add(AuthenticationFactory.CmdletContextParameterName, extensibleParameters[AuthenticationFactory.CmdletContextParameterName]);
}
var authToken = _authenticator.Authenticate(context.Account, context.Environment, context.Tenant.Id, null, "Never", null, optionalParameters);
authToken.AuthorizeRequest((type, token) => request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(type, token));
return authToken;
}, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ internal static void CheckAndEnqueue<T>(this ConcurrentQueue<T> queue, T item)

internal static bool TryDequeueIfNotNull<T>(this ConcurrentQueue<T> queue, out T result)
{
result = default(T);
result = default;
if (null == queue)
{
return false;
Expand Down
Loading
Loading