diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt index 74f7de658..d6de268e9 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt @@ -2,5 +2,6 @@ Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.get -> string? Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.set -> void Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForTestUser(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor? static Microsoft.Identity.Web.TokenAcquisition.ResolveTenant(string? tenant, Microsoft.Identity.Web.MergedOptions! mergedOptions) -> string? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt index d1805fb40..68eb4d560 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt @@ -2,6 +2,8 @@ const Microsoft.Identity.Web.ClaimConstants.Password = "xms_password" -> string! const Microsoft.Identity.Web.ClaimConstants.Username = "xms_username" -> string! Microsoft.Identity.Web.BeforeTokenAcquisitionForApp +Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser Microsoft.Identity.Web.TokenAcquisitionExtensionOptions Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp? +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForTestUser -> Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser? Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt index 74f7de658..d6de268e9 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt @@ -2,5 +2,6 @@ Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.get -> string? Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.set -> void Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForTestUser(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor? static Microsoft.Identity.Web.TokenAcquisition.ResolveTenant(string? tenant, Microsoft.Identity.Web.MergedOptions! mergedOptions) -> string? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt index d1805fb40..68eb4d560 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -2,6 +2,8 @@ const Microsoft.Identity.Web.ClaimConstants.Password = "xms_password" -> string! const Microsoft.Identity.Web.ClaimConstants.Username = "xms_username" -> string! Microsoft.Identity.Web.BeforeTokenAcquisitionForApp +Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser Microsoft.Identity.Web.TokenAcquisitionExtensionOptions Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp? +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForTestUser -> Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser? Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/InternalAPI.Unshipped.txt index 74f7de658..d6de268e9 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/InternalAPI.Unshipped.txt @@ -2,5 +2,6 @@ Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.get -> string? Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.set -> void Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForTestUser(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor? static Microsoft.Identity.Web.TokenAcquisition.ResolveTenant(string? tenant, Microsoft.Identity.Web.MergedOptions! mergedOptions) -> string? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt index d1805fb40..68eb4d560 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt @@ -2,6 +2,8 @@ const Microsoft.Identity.Web.ClaimConstants.Password = "xms_password" -> string! const Microsoft.Identity.Web.ClaimConstants.Username = "xms_username" -> string! Microsoft.Identity.Web.BeforeTokenAcquisitionForApp +Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser Microsoft.Identity.Web.TokenAcquisitionExtensionOptions Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp? +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForTestUser -> Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser? Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/InternalAPI.Unshipped.txt index 74f7de658..d6de268e9 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/InternalAPI.Unshipped.txt @@ -2,5 +2,6 @@ Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.get -> string? Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.set -> void Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForTestUser(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor? static Microsoft.Identity.Web.TokenAcquisition.ResolveTenant(string? tenant, Microsoft.Identity.Web.MergedOptions! mergedOptions) -> string? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt index d1805fb40..68eb4d560 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt @@ -2,6 +2,8 @@ const Microsoft.Identity.Web.ClaimConstants.Password = "xms_password" -> string! const Microsoft.Identity.Web.ClaimConstants.Username = "xms_username" -> string! Microsoft.Identity.Web.BeforeTokenAcquisitionForApp +Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser Microsoft.Identity.Web.TokenAcquisitionExtensionOptions Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp? +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForTestUser -> Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser? Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt index 74f7de658..d6de268e9 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt @@ -2,5 +2,6 @@ Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.get -> string? Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.set -> void Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForTestUser(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor? static Microsoft.Identity.Web.TokenAcquisition.ResolveTenant(string? tenant, Microsoft.Identity.Web.MergedOptions! mergedOptions) -> string? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt index d1805fb40..68eb4d560 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -2,6 +2,8 @@ const Microsoft.Identity.Web.ClaimConstants.Password = "xms_password" -> string! const Microsoft.Identity.Web.ClaimConstants.Username = "xms_username" -> string! Microsoft.Identity.Web.BeforeTokenAcquisitionForApp +Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser Microsoft.Identity.Web.TokenAcquisitionExtensionOptions Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp? +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForTestUser -> Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser? Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt index 74f7de658..d6de268e9 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt @@ -2,5 +2,6 @@ Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.get -> string? Microsoft.Identity.Web.MergedOptions.AppHomeTenantId.set -> void Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForTestUser(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor? static Microsoft.Identity.Web.TokenAcquisition.ResolveTenant(string? tenant, Microsoft.Identity.Web.MergedOptions! mergedOptions) -> string? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 5d7a3e9da..dc1044ecc 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,6 +1,8 @@ const Microsoft.Identity.Web.ClaimConstants.Password = "xms_password" -> string! const Microsoft.Identity.Web.ClaimConstants.Username = "xms_username" -> string! Microsoft.Identity.Web.BeforeTokenAcquisitionForApp +Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser Microsoft.Identity.Web.TokenAcquisitionExtensionOptions Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp? +Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForTestUser -> Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser? Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs index 1c7573616..4d46960cf 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs +++ b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs @@ -357,13 +357,23 @@ public async Task GetAuthenticationResultForUserAsync( } + // Check for extension options for the ROPC flow + TokenAcquisitionExtensionOptions? addInOptions = tokenAcquisitionExtensionOptionsMonitor?.CurrentValue; + // ROPC flow - var authenticationResult = await ((IByUsernameAndPassword)application).AcquireTokenByUsernamePassword( - scopes.Except(_scopesRequestedByMsal), - username, - password) - .ExecuteAsync() - .ConfigureAwait(false); + AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder builder = ((IByUsernameAndPassword)application) + .AcquireTokenByUsernamePassword( + scopes.Except(_scopesRequestedByMsal), + username, + password); + + if (addInOptions != null) + { + addInOptions.InvokeOnBeforeTokenAcquisitionForTestUser(builder, tokenAcquisitionOptions); + } + + var authenticationResult = await builder.ExecuteAsync() + .ConfigureAwait(false); if (user.GetMsalAccountId() == null) { diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensionOptions.cs b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensionOptions.cs index e2a422085..c90dd9f54 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensionOptions.cs +++ b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensionOptions.cs @@ -28,5 +28,22 @@ internal void InvokeOnBeforeTokenAcquisitionForApp(AcquireTokenForClientParamete OnBeforeTokenAcquisitionForApp(builder, acquireTokenOptions); } } + + /// + /// Event fired when a ROPC flow request is being built. + /// + public event BeforeTokenAcquisitionForTestUser? OnBeforeTokenAcquisitionForTestUser; + + /// + /// Invoke the BeforeTokenAcquisitionForTestUser event. + /// + internal void InvokeOnBeforeTokenAcquisitionForTestUser(AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder builder, + AcquireTokenOptions? acquireTokenOptions) + { + if (OnBeforeTokenAcquisitionForTestUser != null) + { + OnBeforeTokenAcquisitionForTestUser(builder, acquireTokenOptions); + } + } } } diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensions.cs b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensions.cs index e4989e54a..9b8fecab8 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensions.cs +++ b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisitionExtensions.cs @@ -13,4 +13,11 @@ namespace Microsoft.Identity.Web /// Builder /// Token acquisition options for the request. Can be null. public delegate void BeforeTokenAcquisitionForApp(AcquireTokenForClientParameterBuilder builder, AcquireTokenOptions? acquireTokenOptions); + + /// + /// Signature for token acquisition extensions that act on the request builder, for ROPC flow. + /// + /// Builder + /// Token acquisition options for the request. Can be null. + public delegate void BeforeTokenAcquisitionForTestUser(AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder builder, AcquireTokenOptions? acquireTokenOptions); } diff --git a/src/Microsoft.Identity.Web/PublicAPI/net462/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web/PublicAPI/net462/PublicAPI.Unshipped.txt index 1fcf3fa79..7dc5c5811 100644 --- a/src/Microsoft.Identity.Web/PublicAPI/net462/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web/PublicAPI/net462/PublicAPI.Unshipped.txt @@ -1,2 +1 @@ #nullable enable -static Microsoft.Identity.Web.ClaimsPrincipalFactory.FromUsernamePassword(string! username, string! password) -> System.Security.Claims.ClaimsPrincipal! diff --git a/src/Microsoft.Identity.Web/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web/PublicAPI/net472/PublicAPI.Unshipped.txt index 1fcf3fa79..7dc5c5811 100644 --- a/src/Microsoft.Identity.Web/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -1,2 +1 @@ #nullable enable -static Microsoft.Identity.Web.ClaimsPrincipalFactory.FromUsernamePassword(string! username, string! password) -> System.Security.Claims.ClaimsPrincipal! diff --git a/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpCreator.cs b/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpCreator.cs index 220ef20ab..e3759c223 100644 --- a/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpCreator.cs +++ b/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpCreator.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System.Collections; +using System.Collections.Generic; using System.Net; using System.Net.Http; using Microsoft.Identity.Web.Util; @@ -55,5 +57,17 @@ public static MockHttpMessageHandler CreateClientCredentialTokenHandler( return handler; } + + public static MockHttpMessageHandler CreateHandlerToValidatePostData( + HttpMethod expectedMethod, + IDictionary expectedPostData) + { + return new MockHttpMessageHandler() + { + ExpectedMethod = expectedMethod, + ExpectedPostData = expectedPostData, + ResponseMessage = CreateSuccessfulClientCredentialTokenResponseMessage(), + }; + } } } diff --git a/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpMessageHandler.cs b/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpMessageHandler.cs index 0d609fd1c..488947ae5 100644 --- a/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpMessageHandler.cs +++ b/tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpMessageHandler.cs @@ -7,6 +7,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using Azure.Core; using Xunit; namespace Microsoft.Identity.Web.Test.Common.Mocks @@ -27,6 +28,8 @@ public MockHttpMessageHandler() public HttpMethod ExpectedMethod { get; set; } + public IDictionary ExpectedPostData { get; set; } + public Exception ExceptionToThrow { get; set; } /// @@ -78,14 +81,28 @@ protected override async Task SendAsync(HttpRequestMessage } Assert.Equal(ExpectedMethod, request.Method); + await ValidatePostDataAsync(request); + + return ResponseMessage; + } + + private async Task ValidatePostDataAsync(HttpRequestMessage request) + { if (request.Method != HttpMethod.Get && request.Content != null) { string postData = await request.Content.ReadAsStringAsync(); ActualRequestPostData = QueryStringParser.ParseKeyValueList(postData, '&', true, false); } - return ResponseMessage; + if (ExpectedPostData != null) + { + foreach (string key in ExpectedPostData.Keys) + { + Assert.True(ActualRequestPostData.ContainsKey(key)); + Assert.Equal(ExpectedPostData[key], ActualRequestPostData[key]); + } + } } } } diff --git a/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAddInTests.cs b/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAddInTests.cs index 1a33fef50..eb5df222a 100644 --- a/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAddInTests.cs +++ b/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAddInTests.cs @@ -7,6 +7,9 @@ using Microsoft.Identity.Web.Test.Common; using Xunit; using System.Threading.Tasks; +using Microsoft.Identity.Client.Extensibility; +using Microsoft.Graph; +using System.Collections.Generic; namespace Microsoft.Identity.Web.Tests { @@ -60,5 +63,55 @@ public async Task InvokeOnBeforeTokenAcquisitionForApp_InvokesEvent() Assert.NotNull(result); Assert.Equal(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); } + + [Fact] + public async Task InvokeOnBeforeTokenAcquisitionForUsernamePassword_InvokesEvent() + { + // Arrange + var options = new TokenAcquisitionExtensionOptions(); + var acquireTokenOptions = new AcquireTokenOptions(); + acquireTokenOptions.ForceRefresh = true; + + //Configure mocks + using MockHttpClientFactory mockHttpClient = new(); + mockHttpClient.AddMockHandler(MockHttpCreator.CreateHandlerToValidatePostData( + System.Net.Http.HttpMethod.Post, + new Dictionary() { { "x-ms-test", "test" } })); + + var confidentialApp = ConfidentialClientApplicationBuilder + .Create(TestConstants.ClientId) + .WithAuthority(TestConstants.AuthorityCommonTenant) + .WithHttpClientFactory(mockHttpClient) + .WithInstanceDiscovery(false) + .WithClientSecret(TestConstants.ClientSecret) + .Build(); + + AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder builder = ((IByUsernameAndPassword)confidentialApp) + .AcquireTokenByUsernamePassword(new string[] { "scope" }, "username", "something"); + + bool eventInvoked = false; + options.OnBeforeTokenAcquisitionForTestUser += (builder, options) => + { + MsalAuthenticationExtension extension = new MsalAuthenticationExtension(); + extension.OnBeforeTokenRequestHandler = (request) => + { + eventInvoked = true; + request.BodyParameters.Add("x-ms-test", "test"); + return Task.CompletedTask; + }; + + builder.WithAuthenticationExtension(extension); + }; + + // Act + options.InvokeOnBeforeTokenAcquisitionForTestUser(builder, acquireTokenOptions); + + var result = await builder.ExecuteAsync(); + + // Assert + Assert.True(eventInvoked); + Assert.NotNull(result); + Assert.Equal(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); + } } }