Skip to content
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

Microsoft.Identity.Web token acquisition extensions #3005

Merged
merged 25 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@

<PropertyGroup Label="Common dependency versions">
<MicrosoftIdentityModelVersion Condition="'$(MicrosoftIdentityModelVersion)' == ''">8.1.0</MicrosoftIdentityModelVersion>
<MicrosoftIdentityClientVersion Condition="'$(MicrosoftIdentityClientVersion)' == ''">4.64.1</MicrosoftIdentityClientVersion>
<MicrosoftIdentityClientVersion Condition="'$(MicrosoftIdentityClientVersion)' == ''">4.65.0-preview</MicrosoftIdentityClientVersion>
<FxCopAnalyzersVersion>3.3.0</FxCopAnalyzersVersion>
<SystemTextEncodingsWebVersion>4.7.2</SystemTextEncodingsWebVersion>
<AzureSecurityKeyVaultSecretsVersion>4.6.0</AzureSecurityKeyVaultSecretsVersion>
Expand Down
4 changes: 4 additions & 0 deletions Microsoft.Identity.Web.sln
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ Global
{BCE63265-6D36-423A-9C3D-BF8E448C7EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BCE63265-6D36-423A-9C3D-BF8E448C7EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BCE63265-6D36-423A-9C3D-BF8E448C7EA0}.Release|Any CPU.Build.0 = Release|Any CPU
{A9592A72-8D33-47F8-A748-DEB4F204BC0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
jennyf19 marked this conversation as resolved.
Show resolved Hide resolved
{A9592A72-8D33-47F8-A748-DEB4F204BC0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
jennyf19 marked this conversation as resolved.
Show resolved Hide resolved
{A9592A72-8D33-47F8-A748-DEB4F204BC0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
jennyf19 marked this conversation as resolved.
Show resolved Hide resolved
{A9592A72-8D33-47F8-A748-DEB4F204BC0D}.Release|Any CPU.Build.0 = Release|Any CPU
jennyf19 marked this conversation as resolved.
Show resolved Hide resolved
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion NuGet.Config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<configuration>
<packageSources>
<clear />
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
jmprieur marked this conversation as resolved.
Show resolved Hide resolved
<add key="IDDP" value="https://identitydivision.pkgs.visualstudio.com/_packaging/IDDP/nuget/v3/index.json" />
</packageSources>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ async Task<AcquireTokenResult> ITokenAcquirer.GetTokenForAppAsync(string scope,
UserFlow = tokenAcquisitionOptions.UserFlow,
PopPublicKey = tokenAcquisitionOptions.PopPublicKey,
PopClaim = tokenAcquisitionOptions.PopClaim,
ExtraParameters = tokenAcquisitionOptions.ExtraParameters,
bgavrilMS marked this conversation as resolved.
Show resolved Hide resolved
};
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.Advanced;
Expand Down Expand Up @@ -57,6 +58,7 @@ class OAuthConstants
protected readonly ITokenAcquisitionHost _tokenAcquisitionHost;
protected readonly ICredentialsLoader _credentialsLoader;
protected readonly ICertificatesObserver? _certificatesObserver;
protected readonly IOptionsMonitor<TokenAcquisitionAddInOptions> tokenAcquisitionAddInOptionsMonitor;

/// <summary>
/// Scopes which are already requested by MSAL.NET. They should not be re-requested;.
Expand Down Expand Up @@ -104,6 +106,7 @@ public TokenAcquisition(
_tokenAcquisitionHost = tokenAcquisitionHost;
_credentialsLoader = credentialsLoader;
_certificatesObserver = serviceProvider.GetService<ICertificatesObserver>();
tokenAcquisitionAddInOptionsMonitor = serviceProvider.GetService<IOptionsMonitor<TokenAcquisitionAddInOptions>>();
}

#if NET6_0_OR_GREATER
Expand Down Expand Up @@ -384,13 +387,21 @@ public async Task<AuthenticationResult> GetAuthenticationResultForAppAsync(
}
}

TokenAcquisitionAddInOptions? addInOptions = tokenAcquisitionAddInOptionsMonitor?.CurrentValue;


// Use MSAL to get the right token to call the API
var application = await GetOrBuildConfidentialClientApplicationAsync(mergedOptions);

AcquireTokenForClientParameterBuilder builder = application
.AcquireTokenForClient(new[] { scope }.Except(_scopesRequestedByMsal))
.WithSendX5C(mergedOptions.SendX5C);

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

// MSAL.net only allows .WithTenantId for AAD authorities. This makes sense as there should
// not be cross tenant operations with such an authority.
if (!mergedOptions.Instance.Contains(Constants.CiamAuthoritySuffix
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Client;

namespace Microsoft.Identity.Web
{
/// <summary>
/// Signature for token acquisition extensions that act on the application builder.
/// </summary>
/// <param name="confidentialClientApplicationBuilder">Application builder.</param>
/// <param name="acquireTokenOptions">Token acquisition options.</param>
public delegate void BuildApplication(ConfidentialClientApplicationBuilder confidentialClientApplicationBuilder, AcquireTokenOptions acquireTokenOptions);

/// <summary>
/// Signature for token acquisition extensions that act on the request builder, for an app token
/// </summary>
/// <param name="builder">Builder</param>
/// <param name="acquireTokenOptions">Token acquisition options for the request.</param>
public delegate void BeforeTokenAcquisitionForApp(AcquireTokenForClientParameterBuilder builder, AcquireTokenOptions acquireTokenOptions);
jmprieur marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Signature for token acquisition extensions that act on the application builder.
/// </summary>
/// <param name="authResult">MSAL.NET authentication result</param>
/// <param name="acquireTokenOptions">Token acquisition options for the request.</param>
public delegate void AfterTokenAcquisition(AuthenticationResult authResult, AcquireTokenOptions acquireTokenOptions);

/// <summary>
/// Options for TokenAcquisition add-ins. These options consist in a set of events, that can be subscribed to by add-ins
/// or parts of the add-ins.
/// </summary>
public class TokenAcquisitionAddInOptions
jmprieur marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Event fired when the MSAL application needs to be built.
/// </summary>
public event BuildApplication? OnBuildConfidentialClientApplication;
jmprieur marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Event fired when a client credential flow request is being built.
/// </summary>
public event BeforeTokenAcquisitionForApp? OnBeforeTokenAcquisitionForApp;


/// <summary>
/// Event fired when an authentication result is available.
/// </summary>
public event AfterTokenAcquisition? OnAfterTokenAcquisition;
jmprieur marked this conversation as resolved.
Show resolved Hide resolved

internal void InvokeOnBuildConfidentialClientApplication(ConfidentialClientApplicationBuilder builder,
AcquireTokenOptions acquireTokenOptions)
{
if (OnBuildConfidentialClientApplication != null)
{
OnBuildConfidentialClientApplication(builder, acquireTokenOptions);
}
}


internal void InvokeOnBeforeTokenAcquisitionForApp(AcquireTokenForClientParameterBuilder builder,
AcquireTokenOptions acquireTokenOptions)
{
if (OnBeforeTokenAcquisitionForApp != null)
{
OnBeforeTokenAcquisitionForApp(builder, acquireTokenOptions);
}
}

internal void InvokeOnAfterTokenAcquisition(AuthenticationResult result,
AcquireTokenOptions acquireTokenOptions)
{
if (OnAfterTokenAcquisition != null)
{
OnAfterTokenAcquisition(result, acquireTokenOptions);
}
}

}
}