Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForUsernamePassword(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Web.TokenAcquisitionExtensionOptions!>?
Original file line number Diff line number Diff line change
Expand Up @@ -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.BeforeTokenAcquisitionForUsernamePassword
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForUsernamePassword -> Microsoft.Identity.Web.BeforeTokenAcquisitionForUsernamePassword?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#nullable enable
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForUsernamePassword(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Web.TokenAcquisitionExtensionOptions!>?

Original file line number Diff line number Diff line change
Expand Up @@ -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.BeforeTokenAcquisitionForUsernamePassword
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForUsernamePassword -> Microsoft.Identity.Web.BeforeTokenAcquisitionForUsernamePassword?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForUsernamePassword(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Web.TokenAcquisitionExtensionOptions!>?
Original file line number Diff line number Diff line change
Expand Up @@ -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.BeforeTokenAcquisitionForUsernamePassword
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForUsernamePassword -> Microsoft.Identity.Web.BeforeTokenAcquisitionForUsernamePassword?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForUsernamePassword(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Web.TokenAcquisitionExtensionOptions!>?
Original file line number Diff line number Diff line change
Expand Up @@ -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.BeforeTokenAcquisitionForUsernamePassword
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForUsernamePassword -> Microsoft.Identity.Web.BeforeTokenAcquisitionForUsernamePassword?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForUsernamePassword(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Web.TokenAcquisitionExtensionOptions!>?
Original file line number Diff line number Diff line change
Expand Up @@ -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.BeforeTokenAcquisitionForUsernamePassword
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForUsernamePassword -> Microsoft.Identity.Web.BeforeTokenAcquisitionForUsernamePassword?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForApp(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForUsernamePassword(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
readonly Microsoft.Identity.Web.TokenAcquisition.tokenAcquisitionExtensionOptionsMonitor -> Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Identity.Web.TokenAcquisitionExtensionOptions!>?
Original file line number Diff line number Diff line change
@@ -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.BeforeTokenAcquisitionForUsernamePassword
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForApp -> Microsoft.Identity.Web.BeforeTokenAcquisitionForApp?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForUsernamePassword -> Microsoft.Identity.Web.BeforeTokenAcquisitionForUsernamePassword?
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.TokenAcquisitionExtensionOptions() -> void
22 changes: 16 additions & 6 deletions src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,23 @@ public async Task<AuthenticationResult> 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);
Comment thread
bgavrilMS marked this conversation as resolved.

if (addInOptions != null)
{
addInOptions.InvokeOnBeforeTokenAcquisitionForUsernamePassword(builder, tokenAcquisitionOptions);
}

var authenticationResult = await builder.ExecuteAsync()
.ConfigureAwait(false);

if (user.GetMsalAccountId() == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,22 @@ internal void InvokeOnBeforeTokenAcquisitionForApp(AcquireTokenForClientParamete
OnBeforeTokenAcquisitionForApp(builder, acquireTokenOptions);
}
}

/// <summary>
/// Event fired when a ROPC flow request is being built.
/// </summary>
public event BeforeTokenAcquisitionForUsernamePassword? OnBeforeTokenAcquisitionForUsernamePassword;
Comment thread
neha-bhargava marked this conversation as resolved.
Outdated

/// <summary>
/// Invoke the BeforeTokenAcquisitionForUsernamePassword event.
/// </summary>
internal void InvokeOnBeforeTokenAcquisitionForUsernamePassword(AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder builder,
AcquireTokenOptions? acquireTokenOptions)
{
if (OnBeforeTokenAcquisitionForUsernamePassword != null)
{
OnBeforeTokenAcquisitionForUsernamePassword(builder, acquireTokenOptions);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@ namespace Microsoft.Identity.Web
/// <param name="builder">Builder</param>
/// <param name="acquireTokenOptions">Token acquisition options for the request. Can be null.</param>
public delegate void BeforeTokenAcquisitionForApp(AcquireTokenForClientParameterBuilder builder, AcquireTokenOptions? acquireTokenOptions);

/// <summary>
/// Signature for token acquisition extensions that act on the request builder, for ROPC flow.
/// </summary>
/// <param name="builder">Builder</param>
/// <param name="acquireTokenOptions">Token acquisition options for the request. Can be null.</param>
public delegate void BeforeTokenAcquisitionForUsernamePassword(AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder builder, AcquireTokenOptions? acquireTokenOptions);
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -55,5 +57,17 @@ public static MockHttpMessageHandler CreateClientCredentialTokenHandler(

return handler;
}

public static MockHttpMessageHandler CreateHandlerToValidatePostData(
HttpMethod expectedMethod,
IDictionary<string, string> expectedPostData)
{
return new MockHttpMessageHandler()
{
ExpectedMethod = expectedMethod,
ExpectedPostData = expectedPostData,
ResponseMessage = CreateSuccessfulClientCredentialTokenResponseMessage(),
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -27,6 +28,8 @@ public MockHttpMessageHandler()

public HttpMethod ExpectedMethod { get; set; }

public IDictionary<string, string> ExpectedPostData { get; set; }

public Exception ExceptionToThrow { get; set; }

/// <summary>
Expand Down Expand Up @@ -79,13 +82,27 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage

Assert.Equal(ExpectedMethod, request.Method);



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]);
}
}
}
}
}
53 changes: 53 additions & 0 deletions tests/Microsoft.Identity.Web.Test/TokenAcquisitionAddInTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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()
Comment thread
neha-bhargava marked this conversation as resolved.
{
// 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<string, string>() { { "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.OnBeforeTokenAcquisitionForUsernamePassword += (builder, options) =>
{
MsalAuthenticationExtension extension = new MsalAuthenticationExtension();
extension.OnBeforeTokenRequestHandler = (request) =>
{
eventInvoked = true;
request.BodyParameters.Add("x-ms-test", "test");
return Task.CompletedTask;
};
Comment thread
neha-bhargava marked this conversation as resolved.

builder.WithAuthenticationExtension(extension);
};

// Act
options.InvokeOnBeforeTokenAcquisitionForUsernamePassword(builder, acquireTokenOptions);

var result = await builder.ExecuteAsync();

// Assert
Assert.True(eventInvoked);
Assert.NotNull(result);
Assert.Equal(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
}
Comment thread
neha-bhargava marked this conversation as resolved.
}
}