Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Expand Up @@ -2,3 +2,4 @@
const Microsoft.Identity.Web.Constants.ClientAssertionContainsInvalidSignature = "AADSTS7000274" -> string!
const Microsoft.Identity.Web.Constants.CertificateWasRevoked = "AADSTS7000277" -> string!
static readonly Microsoft.Identity.Web.Constants.s_certificateRelatedErrorCodes -> System.Collections.Generic.HashSet<string!>!
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForOnBehalfOf -> Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf?
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf.Invoke(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
const Microsoft.Identity.Web.Constants.ClientAssertionContainsInvalidSignature = "AADSTS7000274" -> string!
const Microsoft.Identity.Web.Constants.CertificateWasRevoked = "AADSTS7000277" -> string!
static readonly Microsoft.Identity.Web.Constants.s_certificateRelatedErrorCodes -> System.Collections.Generic.HashSet<string!>!
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForOnBehalfOf -> Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf?
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf.Invoke(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
const Microsoft.Identity.Web.Constants.ClientAssertionContainsInvalidSignature = "AADSTS7000274" -> string!
const Microsoft.Identity.Web.Constants.CertificateWasRevoked = "AADSTS7000277" -> string!
static readonly Microsoft.Identity.Web.Constants.s_certificateRelatedErrorCodes -> System.Collections.Generic.HashSet<string!>!
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForOnBehalfOf -> Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf?
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf.Invoke(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
const Microsoft.Identity.Web.Constants.ClientAssertionContainsInvalidSignature = "AADSTS7000274" -> string!
const Microsoft.Identity.Web.Constants.CertificateWasRevoked = "AADSTS7000277" -> string!
static readonly Microsoft.Identity.Web.Constants.s_certificateRelatedErrorCodes -> System.Collections.Generic.HashSet<string!>!
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForOnBehalfOf -> Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf?
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf.Invoke(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
const Microsoft.Identity.Web.Constants.ClientAssertionContainsInvalidSignature = "AADSTS7000274" -> string!
const Microsoft.Identity.Web.Constants.CertificateWasRevoked = "AADSTS7000277" -> string!
static readonly Microsoft.Identity.Web.Constants.s_certificateRelatedErrorCodes -> System.Collections.Generic.HashSet<string!>!
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForOnBehalfOf -> Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf?
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf.Invoke(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
const Microsoft.Identity.Web.Constants.ClientAssertionContainsInvalidSignature = "AADSTS7000274" -> string!
const Microsoft.Identity.Web.Constants.CertificateWasRevoked = "AADSTS7000277" -> string!
static readonly Microsoft.Identity.Web.Constants.s_certificateRelatedErrorCodes -> System.Collections.Generic.HashSet<string!>!
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf
Microsoft.Identity.Web.TokenAcquisitionExtensionOptions.OnBeforeTokenAcquisitionForOnBehalfOf -> Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf?
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForOnBehalfOf.Invoke(Microsoft.Identity.Client.AcquireTokenOnBehalfOfParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -1156,10 +1156,13 @@ private void NotifyCertificateSelection(
string? tokenUsedToCallTheWebApi = GetActualToken(validatedToken);

AcquireTokenOnBehalfOfParameterBuilder? builder = null;
TokenAcquisitionExtensionOptions? addInOptions = null;

// Case of web APIs: we need to do an on-behalf-of flow, with the token used to call the API
if (tokenUsedToCallTheWebApi != null)
{
addInOptions = tokenAcquisitionExtensionOptionsMonitor?.CurrentValue;

if (string.IsNullOrEmpty(tokenAcquisitionOptions?.LongRunningWebApiSessionKey))
{
builder = application
Expand Down Expand Up @@ -1216,6 +1219,11 @@ private void NotifyCertificateSelection(
}
if (tokenAcquisitionOptions != null)
{
if (addInOptions != null)
{
addInOptions.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(builder, tokenAcquisitionOptions, user!);
}

AddFmiPathForSignedAssertionIfNeeded(tokenAcquisitionOptions, builder);

var dict = MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ internal void InvokeOnBeforeTokenAcquisitionForApp(AcquireTokenForClientParamete
/// </summary>
public event BeforeTokenAcquisitionForTestUserAsync? OnBeforeTokenAcquisitionForTestUserAsync;

/// <summary>
/// Occurs before an asynchronous token acquisition operation for the On-Behalf-Of authentication flow is
/// initiated.
/// </summary>
public event BeforeTokenAcquisitionForOnBehalfOf? OnBeforeTokenAcquisitionForOnBehalfOf;

/// <summary>
/// Invoke the OnBeforeTokenAcquisitionForApp event.
/// </summary>
internal void InvokeOnBeforeTokenAcquisitionForOnBehalfOf(AcquireTokenOnBehalfOfParameterBuilder builder,
AcquireTokenOptions? acquireTokenOptions,
ClaimsPrincipal user)
{
if (OnBeforeTokenAcquisitionForOnBehalfOf != null)
{
OnBeforeTokenAcquisitionForOnBehalfOf(builder, acquireTokenOptions, user);
}
}

/// <summary>
/// Invoke the BeforeTokenAcquisitionForTestUser event.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ namespace Microsoft.Identity.Web
/// <param name="user">User claims.</param>
public delegate Task BeforeTokenAcquisitionForTestUserAsync(AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder builder, AcquireTokenOptions? acquireTokenOptions, ClaimsPrincipal user);

/// <summary>
/// Signature for token acquisition extensions that act on the request builder, for on-behalf-of flow (Async version).
/// </summary>
/// <param name="builder">Builder</param>
/// <param name="acquireTokenOptions">Token acquisition options for the request. Can be null.</param>
/// <param name="user">User claims.</param>
public delegate void BeforeTokenAcquisitionForOnBehalfOf(AcquireTokenOnBehalfOfParameterBuilder builder, AcquireTokenOptions? acquireTokenOptions, ClaimsPrincipal user);
}
51 changes: 51 additions & 0 deletions tests/Microsoft.Identity.Web.Test/TokenAcquisitionAddInTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,56 @@ public async Task InvokeOnBeforeTokenAcquisitionForUsernamePassword_InvokesEvent
Assert.NotNull(result);
Assert.Equal(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
}

[Fact]
public async Task InvokeOnBeforeTokenAcquisitionForOnBehalfOf_InvokesEvent()
{
// Arrange
var options = new TokenAcquisitionExtensionOptions();
var acquireTokenOptions = new AcquireTokenOptions();
acquireTokenOptions.ForceRefresh = true;

//Configure mocks
using MockHttpClientFactory mockHttpClient = new();
mockHttpClient.AddMockHandler(MockHttpCreator.CreateClientCredentialTokenHandler());

var confidentialApp = ConfidentialClientApplicationBuilder
.Create(TestConstants.ClientId)
.WithAuthority(TestConstants.AuthorityCommonTenant)
.WithHttpClientFactory(mockHttpClient)
.WithInstanceDiscovery(false)
.WithClientSecret(TestConstants.ClientSecret)
.Build();

var userAssertion = new UserAssertion("user-assertion-token");
AcquireTokenOnBehalfOfParameterBuilder builder = confidentialApp
.AcquireTokenOnBehalfOf(new string[] { "scope" }, userAssertion);

bool eventInvoked = false;
options.OnBeforeTokenAcquisitionForOnBehalfOf += (builder, options, user) =>
{
eventInvoked = true;

//Set ForceRefresh on the builder
builder.WithForceRefresh(options!.ForceRefresh);
};

var user = new ClaimsPrincipal(
new CaseSensitiveClaimsIdentity(new[]
{
new Claim(ClaimConstants.Sub, "user-id"),
new Claim(ClaimConstants.Name, "Test User"),
}));

// Act
options.InvokeOnBeforeTokenAcquisitionForOnBehalfOf(builder, acquireTokenOptions, user);

var result = await builder.ExecuteAsync();

// Assert
Assert.True(eventInvoked);
Assert.NotNull(result);
Assert.Equal(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
}
}
}
Loading