diff --git a/src/Microsoft.Identity.Web.UI/Microsoft.Identity.Web.UI.xml b/src/Microsoft.Identity.Web.UI/Microsoft.Identity.Web.UI.xml index 6a572875e..82c75e5a6 100644 --- a/src/Microsoft.Identity.Web.UI/Microsoft.Identity.Web.UI.xml +++ b/src/Microsoft.Identity.Web.UI/Microsoft.Identity.Web.UI.xml @@ -1,131 +1,131 @@ - - - - Microsoft.Identity.Web.UI - - - - - Controller used in web apps to manage accounts. - - - - - Constructor of from - This constructor is used by dependency injection. - - Configuration options. - - - - Handles user sign in. - - Authentication scheme. - Redirect URI. - Challenge generating a redirect to Azure AD to sign in the user. - - - - Challenges the user. - - Redirect URI. - Scopes to request. - Login hint. - Domain hint. - Claims. - AAD B2C policy. - Authentication scheme. - Challenge generating a redirect to Azure AD to sign in the user. - - - - Handles the user sign-out. - - Authentication scheme. - Sign out result. - - - - In B2C applications handles the Reset password policy. - - Authentication scheme. - Challenge generating a redirect to Azure AD B2C. - - - - In B2C applications, handles the Edit Profile policy. - - Authentication scheme. - Challenge generating a redirect to Azure AD B2C. - - - - Page presenting the Access denied error. - - - - - Method handling the HTTP GET method. - - - - - Model for the Error page. - - - - - Initializes a new instance of the class. - - Error accessor. - - - - This API supports infrastructure and is not intended to be used - directly from your code. This API may change or be removed in future releases. - - - - - This API supports infrastructure and is not intended to be used - directly from your code. This API may change or be removed in future releases. - - - - - This API supports infrastructure and is not intended to be used - directly from your code. This API may change or be removed in future releases. - - - - - This API supports infrastructure and is not intended to be used - directly from your code. This API may change or be removed in future releases. - - - - - Model for the SignOut page. - - - - - Method handling the HTTP GET method. - - A Sign Out page or Home page. - - - - Extension method on to add UI - for Microsoft.Identity.Web. - - - - - Adds a controller and Razor pages for the accounts management. - - MVC builder. - MVC builder for chaining. - - - + + + + Microsoft.Identity.Web.UI + + + + + Controller used in web apps to manage accounts. + + + + + Constructor of from + This constructor is used by dependency injection. + + Configuration options. + + + + Handles user sign in. + + Authentication scheme. + Redirect URI. + Challenge generating a redirect to Azure AD to sign in the user. + + + + Challenges the user. + + Redirect URI. + Scopes to request. + Login hint. + Domain hint. + Claims. + AAD B2C policy. + Authentication scheme. + Challenge generating a redirect to Azure AD to sign in the user. + + + + Handles the user sign-out. + + Authentication scheme. + Sign out result. + + + + In B2C applications handles the Reset password policy. + + Authentication scheme. + Challenge generating a redirect to Azure AD B2C. + + + + In B2C applications, handles the Edit Profile policy. + + Authentication scheme. + Challenge generating a redirect to Azure AD B2C. + + + + Page presenting the Access denied error. + + + + + Method handling the HTTP GET method. + + + + + Model for the Error page. + + + + + Initializes a new instance of the class. + + Error accessor. + + + + This API supports infrastructure and is not intended to be used + directly from your code. This API may change or be removed in future releases. + + + + + This API supports infrastructure and is not intended to be used + directly from your code. This API may change or be removed in future releases. + + + + + This API supports infrastructure and is not intended to be used + directly from your code. This API may change or be removed in future releases. + + + + + This API supports infrastructure and is not intended to be used + directly from your code. This API may change or be removed in future releases. + + + + + Model for the SignOut page. + + + + + Method handling the HTTP GET method. + + A Sign Out page or Home page. + + + + Extension method on to add UI + for Microsoft.Identity.Web. + + + + + Adds a controller and Razor pages for the accounts management. + + MVC builder. + MVC builder for chaining. + + + diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs index 8c3e11d18..d786115bf 100644 --- a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs @@ -10,7 +10,7 @@ namespace Microsoft.Identity.Web /// Options passed-in to call downstream web APIs. To call Microsoft Graph, see rather /// MicrosoftGraphOptions in the Microsoft.Identity.Web.MicrosoftGraph assembly. /// - public class DownstreamWebApiOptions : ICloneable + public class DownstreamWebApiOptions : MicrosoftIdentityAuthenticationBaseOptions, ICloneable { /// /// Base URL for the called downstream web API. For instance "https://graph.microsoft.com/beta/".. @@ -22,51 +22,11 @@ public class DownstreamWebApiOptions : ICloneable /// public string RelativePath { get; set; } = string.Empty; - /// - /// Space separated scopes required to call the downstream web API. - /// For instance "user.read mail.read". - /// - public string? Scopes { get; set; } - - /// - /// [Optional] tenant ID. This is used for specific scenarios where - /// the application needs to call a downstream web API on behalf of a user in several tenants. - /// It would mostly be used from code, not from the configuration. - /// - public string? Tenant { get; set; } - - /// - /// [Optional]. User flow (in the case of a B2C downstream web API). If not - /// specified, the B2C downstream web API will be called with the default user flow from - /// . - /// - public string? UserFlow { get; set; } - /// /// HTTP method used to call this downstream web API (by default Get). /// public HttpMethod HttpMethod { get; set; } = HttpMethod.Get; - /// - /// Modifies the token acquisition request so that the acquired token is a Proof of Possession token (PoP), - /// rather than a Bearer token. - /// PoP tokens are similar to Bearer tokens, but are bound to the HTTP request and to a cryptographic key, - /// which MSAL can manage. See https://aka.ms/msal-net-pop. - /// Set to true to enable PoP tokens automatically. - /// - public bool IsProofOfPossessionRequest { get; set; } - - /// - /// Options passed-in to create the token acquisition object which calls into MSAL .NET. - /// - public TokenAcquisitionOptions TokenAcquisitionOptions { get; set; } = new TokenAcquisitionOptions(); - - /// - /// Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme - /// if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. - /// - public string? AuthenticationScheme { get; set; } - /// /// Clone the options (to be able to override them). /// @@ -97,15 +57,6 @@ public string GetApiUrl() return BaseUrl?.TrimEnd('/') + $"/{RelativePath}"; } - /// - /// Returns the scopes. - /// - /// Scopes. - public string[] GetScopes() - { - return string.IsNullOrWhiteSpace(Scopes) ? new string[0] : Scopes.Split(' '); - } - /// /// Clone the options (to be able to override them). /// diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAppAuthenticationMessageHandler.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAppAuthenticationMessageHandler.cs new file mode 100644 index 000000000..ec4b59003 --- /dev/null +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAppAuthenticationMessageHandler.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.Extensions.Options; + +namespace Microsoft.Identity.Web +{ + /// + /// A DelegatingHandler implementation that add an authorization header with a token for the application. + /// + public class MicrosoftIdentityAppAuthenticationMessageHandler : MicrosoftIdentityAuthenticationBaseMessageHandler + { + /// + /// Initializes a new instance of the class. + /// + /// Token acquisition service. + /// Named options provider. + /// Name of the service describing the downstream web API. + public MicrosoftIdentityAppAuthenticationMessageHandler( + ITokenAcquisition tokenAcquisition, + IOptionsMonitor namedMessageHandlerOptions, + string? serviceName = null) + : base(tokenAcquisition, namedMessageHandlerOptions, serviceName) + { + } + + /// + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + // validate arguments + if (request == null) + { + throw new ArgumentNullException(nameof(request)); + } + + // authenticate + var options = GetOptionsForRequest(request); + + var authResult = await TokenAcquisition.GetAuthenticationResultForAppAsync( + options.Scopes!, + options.AuthenticationScheme, + options.Tenant, + options.TokenAcquisitionOptions) + .ConfigureAwait(false); + + // add or replace authorization header + if (request.Headers.Contains(Constants.Authorization)) + { + request.Headers.Remove(Constants.Authorization); + } + + request.Headers.Add( + Constants.Authorization, + authResult.CreateAuthorizationHeader()); + + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationBaseMessageHandler.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationBaseMessageHandler.cs new file mode 100644 index 000000000..2bee60917 --- /dev/null +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationBaseMessageHandler.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Net.Http; + +using Microsoft.Extensions.Options; +using Microsoft.Identity.Client.AppConfig; + +namespace Microsoft.Identity.Web +{ + /// + /// Base class for Microsoft Identity authentication message handlers. + /// + public abstract class MicrosoftIdentityAuthenticationBaseMessageHandler : DelegatingHandler + { + private readonly IOptionsMonitor _namedMessageHandlerOptions; + private readonly string? _serviceName; + + /// + /// Gets the token acquisition service. + /// + protected ITokenAcquisition TokenAcquisition { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Token acquisition service. + /// Named options provider. + /// Name of the service describing the downstream web API. + protected MicrosoftIdentityAuthenticationBaseMessageHandler( + ITokenAcquisition tokenAcquisition, + IOptionsMonitor namedMessageHandlerOptions, + string? serviceName = null) + { + TokenAcquisition = tokenAcquisition; + _namedMessageHandlerOptions = namedMessageHandlerOptions; + _serviceName = serviceName; + } + + /// + /// Gets the options for the specified request. + /// + /// The request. + /// The configured options. + protected MicrosoftIdentityAuthenticationMessageHandlerOptions GetOptionsForRequest(HttpRequestMessage request) + { + if (request == null) + { + throw new ArgumentNullException(nameof(request)); + } + + var options = _serviceName == null + ? _namedMessageHandlerOptions.CurrentValue + : _namedMessageHandlerOptions.Get(_serviceName); + + if (string.IsNullOrEmpty(options.Scopes)) + { + throw new ArgumentException(IDWebErrorMessage.ScopesNotConfiguredInConfigurationOrViaDelegate); + } + + // clone before overriding with request specific data + options = options.Clone(); + CreateProofOfPossessionConfiguration(options, request.RequestUri!, request.Method); + + return options; + } + + private static void CreateProofOfPossessionConfiguration(MicrosoftIdentityAuthenticationMessageHandlerOptions options, Uri apiUri, HttpMethod method) + { + if (options.IsProofOfPossessionRequest) + { + if (options.TokenAcquisitionOptions == null) + { + options.TokenAcquisitionOptions = new TokenAcquisitionOptions(); + } + + options.TokenAcquisitionOptions.PoPConfiguration = new PoPAuthenticationConfiguration(apiUri) + { + HttpMethod = method, + }; + } + } + } +} diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationBaseOptions.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationBaseOptions.cs new file mode 100644 index 000000000..b630bb79a --- /dev/null +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationBaseOptions.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Microsoft.Identity.Web +{ + /// + /// Base options passed-in to authenticate with Microsoft Identity. + /// + public abstract class MicrosoftIdentityAuthenticationBaseOptions + { + /// + /// Space separated scopes required to call the downstream web API. + /// For instance "user.read mail.read". + /// + public string? Scopes { get; set; } + + /// + /// [Optional] tenant ID. This is used for specific scenarios where + /// the application needs to call a downstream web API on behalf of a user in several tenants. + /// It would mostly be used from code, not from the configuration. + /// + public string? Tenant { get; set; } + + /// + /// [Optional]. User flow (in the case of a B2C downstream web API). If not + /// specified, the B2C downstream web API will be called with the default user flow from + /// . + /// + public string? UserFlow { get; set; } + + /// + /// Modifies the token acquisition request so that the acquired token is a Proof of Possession token (PoP), + /// rather than a Bearer token. + /// PoP tokens are similar to Bearer tokens, but are bound to the HTTP request and to a cryptographic key, + /// which MSAL can manage. See https://aka.ms/msal-net-pop. + /// Set to true to enable PoP tokens automatically. + /// + public bool IsProofOfPossessionRequest { get; set; } + + /// + /// Options passed-in to create the token acquisition object which calls into MSAL .NET. + /// + public TokenAcquisitionOptions TokenAcquisitionOptions { get; set; } = new TokenAcquisitionOptions(); + + /// + /// Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + /// if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + /// + public string? AuthenticationScheme { get; set; } + + /// + /// Returns the scopes. + /// + /// Scopes. + public string[] GetScopes() + { + return string.IsNullOrWhiteSpace(Scopes) ? new string[0] : Scopes.Split(' '); + } + } +} diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationMessageHandlerHttpClientBuilderExtensions.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationMessageHandlerHttpClientBuilderExtensions.cs new file mode 100644 index 000000000..ce53d46e4 --- /dev/null +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationMessageHandlerHttpClientBuilderExtensions.cs @@ -0,0 +1,135 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace Microsoft.Identity.Web +{ + /// + /// Extension for IHttpClientBuilder for startup initialization of Microsoft Identity authentication handlers. + /// + public static class MicrosoftIdentityAuthenticationMessageHandlerHttpClientBuilderExtensions + { + /// + /// Adds a named Microsoft Identity user authentication message handler related to a specific configuration section. + /// + /// Builder. + /// Name of the configuration for the service. + /// Configuration. + /// The builder for chaining. + public static IHttpClientBuilder AddMicrosoftIdentityUserAuthenticationHandler( + this IHttpClientBuilder builder, + string serviceName, + IConfiguration configuration) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Services.Configure(serviceName, configuration); + builder.AddHttpMessageHandler(services => + { + return new MicrosoftIdentityUserAuthenticationMessageHandler( + services.GetRequiredService(), + services.GetRequiredService>(), + services.GetRequiredService>(), + serviceName); + }); + + return builder; + } + + /// + /// Adds a named Microsoft Identity user authentication message handler initialized with delegates. + /// + /// Builder. + /// Name of the configuration for the service. + /// Action to configure the options. + /// The builder for chaining. + public static IHttpClientBuilder AddMicrosoftIdentityUserAuthenticationHandler( + this IHttpClientBuilder builder, + string serviceName, + Action configureOptions) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Services.Configure(serviceName, configureOptions); + builder.AddHttpMessageHandler(services => + { + return new MicrosoftIdentityUserAuthenticationMessageHandler( + services.GetRequiredService(), + services.GetRequiredService>(), + services.GetRequiredService>(), + serviceName); + }); + + return builder; + } + + /// + /// Adds a named Microsoft Identity application authentication message handler related to a specific configuration section. + /// + /// Builder. + /// Name of the configuration for the service. + /// Configuration. + /// The builder for chaining. + public static IHttpClientBuilder AddMicrosoftIdentityAppAuthenticationHandler( + this IHttpClientBuilder builder, + string serviceName, + IConfiguration configuration) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Services.Configure(serviceName, configuration); + builder.AddHttpMessageHandler(services => + { + return new MicrosoftIdentityAppAuthenticationMessageHandler( + services.GetRequiredService(), + services.GetRequiredService>(), + serviceName); + }); + + return builder; + } + + /// + /// Adds a named Microsoft Identity application authentication message handler initialized with delegates. + /// + /// Builder. + /// Name of the configuration for the service. + /// Action to configure the options. + /// The builder for chaining. + public static IHttpClientBuilder AddMicrosoftIdentityAppAuthenticationHandler( + this IHttpClientBuilder builder, + string serviceName, + Action configureOptions) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.Services.Configure(serviceName, configureOptions); + builder.AddHttpMessageHandler(services => + { + return new MicrosoftIdentityAppAuthenticationMessageHandler( + services.GetRequiredService(), + services.GetRequiredService>(), + serviceName); + }); + + return builder; + } + } +} diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationMessageHandlerOptions.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationMessageHandlerOptions.cs new file mode 100644 index 000000000..3c77dff5f --- /dev/null +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAuthenticationMessageHandlerOptions.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Microsoft.Identity.Web +{ + /// + /// Options passed-in to Microsoft Identity message handlers. + /// + public class MicrosoftIdentityAuthenticationMessageHandlerOptions : MicrosoftIdentityAuthenticationBaseOptions, ICloneable + { + /// + /// Clone the options (to be able to override them). + /// + /// A clone of the options. + public MicrosoftIdentityAuthenticationMessageHandlerOptions Clone() + { + return new MicrosoftIdentityAuthenticationMessageHandlerOptions + { + Scopes = Scopes, + Tenant = Tenant, + UserFlow = UserFlow, + IsProofOfPossessionRequest = IsProofOfPossessionRequest, + TokenAcquisitionOptions = TokenAcquisitionOptions.Clone(), + AuthenticationScheme = AuthenticationScheme, + }; + } + + /// + /// Clone the options (to be able to override them). + /// + /// A clone of the options. + object ICloneable.Clone() + { + return Clone(); + } + } +} diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityUserAuthenticationMessageHandler.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityUserAuthenticationMessageHandler.cs new file mode 100644 index 000000000..211bbc60b --- /dev/null +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityUserAuthenticationMessageHandler.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.Extensions.Options; + +namespace Microsoft.Identity.Web +{ + /// + /// A DelegatingHandler implementation that add an authorization header with a token on behalf of the current user. + /// + public class MicrosoftIdentityUserAuthenticationMessageHandler : MicrosoftIdentityAuthenticationBaseMessageHandler + { + private readonly IOptionsMonitor _microsoftIdentityOptions; + + /// + /// Initializes a new instance of the class. + /// + /// Token acquisition service. + /// Named options provider. + /// Configuration options. + /// Name of the service describing the downstream web API. + public MicrosoftIdentityUserAuthenticationMessageHandler( + ITokenAcquisition tokenAcquisition, + IOptionsMonitor namedMessageHandlerOptions, + IOptionsMonitor microsoftIdentityOptions, + string? serviceName = null) + : base(tokenAcquisition, namedMessageHandlerOptions, serviceName) + { + _microsoftIdentityOptions = microsoftIdentityOptions; + } + + /// + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + // validate arguments + if (request == null) + { + throw new ArgumentNullException(nameof(request)); + } + + // authenticate + var options = GetOptionsForRequest(request); + var microsoftIdentityOptions = _microsoftIdentityOptions + .Get(TokenAcquisition.GetEffectiveAuthenticationScheme(options.AuthenticationScheme)); + + var userflow = microsoftIdentityOptions.IsB2C && string.IsNullOrEmpty(options.UserFlow) + ? microsoftIdentityOptions.DefaultUserFlow + : options.UserFlow; + + var authResult = await TokenAcquisition.GetAuthenticationResultForUserAsync( + options.GetScopes(), + authenticationScheme: options.AuthenticationScheme, + tenantId: options.Tenant, + userFlow: userflow, + tokenAcquisitionOptions: options.TokenAcquisitionOptions) + .ConfigureAwait(false); + + // add or replace authorization header + if (request.Headers.Contains(Constants.Authorization)) + { + request.Headers.Remove(Constants.Authorization); + } + + request.Headers.Add( + Constants.Authorization, + authResult.CreateAuthorizationHeader()); + + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml b/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml index cde390086..81d737e9f 100644 --- a/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml +++ b/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml @@ -1,1065 +1,3593 @@ - - - - Microsoft.Identity.Web - - - - - Description of a certificate. - - - - - Creates a certificate description from a certificate (by code). - - Certificate. - A certificate description. - - - - Creates a certificate description from Key Vault. - - The Key Vault URL. - The name of the certificate in Key Vault. - A certificate description. - - - - Creates a certificate description from a Base64 encoded value. - - Base64 encoded certificate value. - A certificate description. - - - - Creates a certificate description from path on disk. - - Path where to find the certificate file. - Certificate password. - A certificate description. - - - - Creates a certificate description from a thumbprint and store location (Certificate Manager on Windows, for instance). - - Certificate thumbprint. - Store location where to find the certificate. - Store name where to find the certificate. - A certificate description. - - - - Creates a certificate description from a thumbprint and store location (Certificate Manager on Windows, for instance). - - Certificate thumbprint. - Store location where to find the certificate. - Store name where to find the certificate. - A certificate description. - - - - Creates a certificate description from a certificate distinguished name (such as CN=name) - and store location (Certificate Manager on Windows, for instance). - - Certificate distinguished named. - Store location where to find the certificate. - Store name where to find the certificate. - A certificate description. - - - - Type of the source of the certificate. - - - - - Container in which to find the certificate. - - If equals , then - the container is the Key Vault base URL. - If equals , then - this value is not used. - If equals , then - this value is the path on disk where to find the certificate. - If equals , - or , then - this value is the path to the certificate in the cert store, for instance CurrentUser/My. - - - - - - URL of the Key Vault, for instance https://msidentitywebsamples.vault.azure.net. - - - - - Certificate store path, for instance "CurrentUser/My". - - This property should only be used in conjunction with DistinguishedName or Thumbprint. - - - - Certificate distinguished name. - - - - - Name of the certificate in Key Vault. - - - - - Certificate thumbprint. - - - - - Path on disk to the certificate. - - - - - Path on disk to the certificate password. - - - - - Base64 encoded certificate value. - - - - - Defines where and how to import the private key of an X.509 certificate. - - - - - Reference to the certificate or value. - - - If equals , then - the reference is the name of the certificate in Key Vault (maybe the version?). - If equals , then - this value is the base 64 encoded certificate itself. - If equals , then - this value is the password to access the certificate (if needed). - If equals , - this value is the distinguished name. - If equals , - this value is the thumbprint. - - - - - The certificate, either provided directly in code - or loaded from the description. - - - - - Source for a certificate. - - - - - Certificate itself. - - - - - From an Azure Key Vault. - - - - - Base64 encoded string directly from the configuration. - - - - - From local path on disk. - - - - - From the certificate store, described by its thumbprint. - - - - - From the certificate store, described by its distinguished name. - - - - - Certificate Loader. - Only use when loading a certificate from a daemon application, or an ASP NET app, using MSAL .NET directly. - For an ASP NET Core app, Microsoft Identity Web will handle the certificate loading for you. - - IConfidentialClientApplication app; - ICertificateLoader certificateLoader = new DefaultCertificateLoader(); - certificateLoader.LoadIfNeeded(config.CertificateDescription); - - app = ConfidentialClientApplicationBuilder.Create(config.ClientId) - .WithCertificate(config.CertificateDescription.Certificate) - .WithAuthority(new Uri(config.Authority)) - .Build(); - - - - - - User assigned managed identity client ID (as opposed to system assigned managed identity) - See https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-portal. - - - - - Load the certificate from the description, if needed. - - Description of the certificate. - - - - Load a certificate from Key Vault, including the private key. - - URL of Key Vault. - Name of the certificate. - Defines where and how to import the private key of an X.509 certificate. - An certificate. - This code is inspired by Heath Stewart's code in: - https://github.com/heaths/azsdk-sample-getcert/blob/master/Program.cs#L46-L82. - - - - - Find a certificate by criteria. - - - - - Interface to implement loading of a certificate. - Only use when loading a certificate from a daemon application, or an ASP NET app, using MSAL .NET directly. - For an ASP NET Core app, Microsoft Identity Web will handle the certificate loading for you. - - IConfidentialClientApplication app; - ICertificateLoader certificateLoader = new DefaultCertificateLoader(); - certificateLoader.LoadIfNeeded(config.CertificateDescription); - - app = ConfidentialClientApplicationBuilder.Create(config.ClientId) - .WithCertificate(config.CertificateDescription.Certificate) - .WithAuthority(new Uri(config.Authority)) - .Build(); - - - - - - Load the certificate from the description, if needed. - - Description of the certificate. - - - - Constants for claim types. - - - - - Name claim: "name". - - - - - Old Object Id claim: http://schemas.microsoft.com/identity/claims/objectidentifier. - - - - - New Object id claim: "oid". - - - - - PreferredUserName: "preferred_username". - - - - - Old TenantId claim: "http://schemas.microsoft.com/identity/claims/tenantid". - - - - - New Tenant Id claim: "tid". - - - - - ClientInfo claim: "client_info". - - - - - UniqueObjectIdentifier: "uid". - Home Object Id. - - - - - UniqueTenantIdentifier: "utid". - Home Tenant Id. - - - - - Older scope claim: "http://schemas.microsoft.com/identity/claims/scope". - - - - - Newer scope claim: "scp". - - - - - New Roles claim = "roles". - - - - - Old Role claim: "http://schemas.microsoft.com/ws/2008/06/identity/claims/role". - - - - - Subject claim: "sub". - - - - - Acr claim: "acr". - - - - - UserFlow claim: "http://schemas.microsoft.com/claims/authnclassreference". - - - - - Tfp claim: "tfp". - - - - - Name Identifier ID claim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier". - - - - - General constants for Microsoft Identity Web. - - - - - LoginHint. - Represents the preferred_username claim in the ID token. - - - - - DomainHint. - Determined by the tenant Id. - - - - - Claims. - Determined from the signed-in user. - - - - - Bearer. - Predominant type of access token used with OAuth 2.0. - - - - - AzureAd. - Configuration section name for AzureAd. - - - - - AzureAdB2C. - Configuration section name for AzureAdB2C. - - - - - Scope. - - - - - Policy for B2C user flows. - The name of the policy to check against a specific user flow. - - - - - Constants related to the error messages. - - - - - Constants related to the log messages. - - - - - Set of properties that the token cache serialization implementations might use to optimize the cache. - - - - - CancellationToken enabling cooperative cancellation between threads, thread pool, or Task objects. - - - - - Suggested cache expiry based on the in-coming token. Use to optimize cache eviction - with the app token cache. - - - - - Extension class used to add distributed token cache serializer to MSAL. - See https://aka.ms/ms-id-web/token-cache-serialization for details. - - - - Adds the .NET Core distributed cache based app token cache to the service collection. - The services collection to add to. - A to chain. - - - - An implementation of the token cache for both Confidential and Public clients backed by a Distributed Cache. - The Distributed Cache (L2), by default creates a Memory Cache (L1), for faster look up, resulting in a two level cache. - - https://aka.ms/msal-net-token-cache-serialization - - LoggingMessage class for MsalDistributedTokenCacheAdapter. - - - - - .NET Core Memory cache. - - - - - MSAL distributed token cache options. - - - - - Initializes a new instance of the class. - - Distributed cache instance to use. - Options for the token cache. - MsalDistributedTokenCacheAdapter logger. - Service provider. Can be null, in which case the token cache - will not be encrypted. See https://aka.ms/ms-id-web/token-cache-encryption. - - - - Removes a specific token cache, described by its cache key - from the distributed cache. - - Key of the cache to remove. - A that completes when key removal has completed. - - - - Removes a specific token cache, described by its cache key - from the distributed cache. - - Key of the cache to remove. - Hints for the cache serialization implementation optimization. - A that completes when key removal has completed. - - - - Read a specific token cache, described by its cache key, from the - distributed cache. - - Key of the cache item to retrieve. - Read blob representing a token cache for the cache key - (account or app). - - - - Read a specific token cache, described by its cache key, from the - distributed cache. - - Key of the cache item to retrieve. - Hints for the cache serialization implementation optimization. - Read blob representing a token cache for the cache key - (account or app). - - - - Writes a token cache blob to the serialization cache (by key). - - Cache key. - blob to write. - A that completes when a write operation has completed. - - - - Writes a token cache blob to the serialization cache (by key). - - Cache key. - blob to write. - Hints for the cache serialization implementation optimization. - A that completes when a write operation has completed. - - - - LoggingMessage class for MsalDistributedTokenCacheAdapter. - - - - - Memory cache remove. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - MSAL.NET cache key. - Cache size in bytes, or 0 if empty. - Exception. - - - - Memory cache remove. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - MSAL.NET cache key. - Exception. - - - - Memory cache count. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - L1 cache count. - Exception. - - - - L2 cache state logging. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - MSAL.NET cache key. - Cache size in bytes, or 0 if empty. - L2 cache retry due to possible connection issue. - Exception. - - - - L2 cache state logging. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - MSAL.NET cache key. - Cache size in bytes, or 0 if empty. - L2 cache retry due to possible connection issue. - Time in milliseconds. - Exception. - - - - L2 cache retry. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - MSAL.NET cache key. - Exception. - - - - L2 cache retry. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - Time in milliseconds. - Exception. - - - - L2 cache error. - - ILogger. - Distributed or Memory. - Cache operation (Read, Write, etc...). - L2 cache retry due to possible connection issue. - Error message. - Exception. - - - - Back propagate L2 to L1. - - ILogger. - Cache size in bytes, or 0 if empty. - Exception. - - - - Options for the MSAL token cache serialization adapter, - which delegates the serialization to the IDistributedCache implementations - available with .NET Core. - - - - - Options of the In Memory (L1) cache. - - - - - Callback offered to the app to be notified when the L2 cache fails. - This way the app is given the possibility to act on the L2 cache, - for instance, in the case of Redis, to reconnect. This is left to the application as it's - the only one that knows about the real implementation of the L2 cache. - The handler should return true if the cache should try again the operation, and - false otherwise. When true is passed and the retry fails, an exception - will be thrown. - - - - - Value more than 0, less than 1, to set the In Memory (L1) cache - expiration time values relative to the Distributed (L2) cache. - Default is 1. - - - - - Should the token cache be encrypted. - - The default is false. - - - - MSAL token cache provider interface. - - - - - Initializes a token cache (which can be a user token cache or an app token cache). - - Token cache for which to initialize the serialization. - A that represents a completed initialization operation. - - - - Initializes a token cache (which can be a user token cache or an app token cache). - - Token cache for which to initialize the serialization. - - - - Clear the user token cache. - - HomeAccountId for a user account in the cache. - A that represents a completed clear operation. - - - - Extension class used to add an in-memory token cache serializer to MSAL. - - - - Adds both the app and per-user in-memory token caches. - The services collection to add to. - the services (for chaining). - - - - MSAL's in-memory token cache options. - - - - Initializes a new instance of the class. - By default, the sliding expiration is set for 14 days. - - - - Gets or sets the value of the duration after which the cache entry will expire unless it's used - This is the duration the tokens are kept in memory cache. - In production, a higher value, up-to 90 days is recommended. - - - The AbsoluteExpirationRelativeToNow value. - - - - - An implementation of token cache for both Confidential and Public clients backed by MemoryCache. - - https://aka.ms/msal-net-token-cache-serialization - - - - .NET Core Memory cache. - - - - - MSAL memory token cache options. - - - - - Constructor. - - serialization cache. - Memory cache options. - - - - Removes a token cache identified by its key, from the serialization - cache. - - token cache key. - A that completes when key removal has completed. - - - - Reads a blob from the serialization cache (identified by its key). - - Token cache key. - Read Bytes. - - - - Writes a token cache blob to the serialization cache (identified by its key). - - Token cache key. - Bytes to write. - A that completes when a write operation has completed. - - - - Writes a token cache blob to the serialization cache (identified by its key). - - Token cache key. - Bytes to write. - Hints for the cache serialization implementation optimization. - A that completes when a write operation has completed. - - - - Token cache provider with default implementation. - - - - - - Constructor. - - Service provider. Can be null, in which case the token cache - will not be encrypted. See https://aka.ms/ms-id-web/token-cache-encryption. - - - - Initializes the token cache serialization. - - Token cache to serialize/deserialize. - - - - Initializes the token cache serialization. - - Token cache to serialize/deserialize. - A that represents a completed initialization operation. - - - - Raised AFTER MSAL added the new token in its in-memory copy of the cache. - This notification is called every time MSAL accesses the cache, not just when a write takes place: - If MSAL's current operation resulted in a cache change, the property TokenCacheNotificationArgs.HasStateChanged will be set to true. - If that is the case, we call the TokenCache.SerializeMsalV3() to get a binary blob representing the latest cache content – and persist it. - - Contains parameters used by the MSAL call accessing the cache. - - - - If you want to ensure that no concurrent write takes place, use this notification to place a lock on the entry. - - Token cache notification arguments. - A that represents a completed operation. - - - - Clear the cache. - - HomeAccountId for a user account in the cache. - A that represents a completed clear operation. - - - - Method to be implemented by concrete cache serializers to write the cache bytes. - - Cache key. - Bytes to write. - A that represents a completed write operation. - - - - Method to be overridden by concrete cache serializers to write the cache bytes. - - Cache key. - Bytes to write. - Hints for the cache serialization implementation optimization. - A that represents a completed write operation. - - - - Method to be implemented by concrete cache serializers to Read the cache bytes. - - Cache key. - Read bytes. - - - - Method to be overridden by concrete cache serializers to Read the cache bytes. - - Cache key. - Hints for the cache serialization implementation optimization. - Read bytes. - - - - Method to be implemented by concrete cache serializers to remove an entry from the cache. - - Cache key. - A that represents a completed remove key operation. - - - - Method to be overridden by concrete cache serializers to remove an entry from the cache. - - Cache key. - Hints for the cache serialization implementation optimization. - A that represents a completed remove key operation. - - - - Utility methods used by L1/L2 cache. - - - - - Extension methods to expose a simplified developer experience for - adding token caches to MSAL.NET confidential client applications - in ASP.NET, or .NET Core, or .NET FW. - - - - - Use a token cache and choose the serialization part by adding it to - the services collection and configuring its options. - - The confidential client application. - Confidential client application. - Action that you'll use to add a cache serialization - to the service collection passed as an argument. - The application for chaining. - - - The following code adds a distributed in-memory token cache. - - - app.AddTokenCaches(services => - { - // In memory distributed token cache - // In net472, requires to reference Microsoft.Extensions.Caching.Memory - services.AddDistributedTokenCache(); - services.AddDistributedMemoryCache(); - }); - - - The following code adds a token cache based on REDIS and initializes - its configuration. - - - app.AddTokenCaches(services => - { - services.AddDistributedTokenCache(); - // Redis token cache - // Requires to reference Microsoft.Extensions.Caching.StackExchangeRedis - services.AddStackExchangeRedisCache(options => - { - options.Configuration = "localhost"; - options.InstanceName = "Redis"; - }); - }); - - If using distributed token caches, use AddDistributedTokenCache. - - Don't use this method in ASP.NET Core. Just add use the ConfigureServices method - instead. - - - - Add an in-memory well partitioned token cache to MSAL.NET confidential client - application. Don't use this method in ASP.NET Core: rather use: - services.AddInMemoryTokenCache() in ConfigureServices. - - Confidential client application. - The application for chaining. - - - The following code adds an in-memory token cache. - - - app.AddInMemoryTokenCache(); - - - - Don't use this method in ASP.NET Core. Just add use the ConfigureServices method - instead. - - - - Add a distributed token cache. - - Confidential client application. - Action taking a - and by which you initialize your distributed cache. - The application for chaining. - - The following code adds a token cache based on REDIS and initializes - its configuration. - - - app.AddDistributedTokenCache(services => - { - // Redis token cache - // Requires to reference Microsoft.Extensions.Caching.StackExchangeRedis - services.AddStackExchangeRedisCache(options => - { - options.Configuration = "localhost"; - options.InstanceName = "Redis"; - }); - }); - - - - Don't use this method in ASP.NET Core. Just add use the ConfigureServices method - instead. - - - - Extensions for . - - - - - Gets the account identifier for an MSAL.NET account from a . - - Claims principal. - A string corresponding to an account identifier as defined in . - - - - Gets the unique object ID associated with the . - - The from which to retrieve the unique object ID. - This method returns the object ID both in case the developer has enabled or not claims mapping. - Unique object ID of the identity, or null if it cannot be found. - - - - Gets the Tenant ID associated with the . - - The from which to retrieve the tenant ID. - Tenant ID of the identity, or null if it cannot be found. - This method returns the tenant ID both in case the developer has enabled or not claims mapping. - - - - Gets the login-hint associated with a . - - Identity for which to complete the login-hint. - The login hint for the identity, or null if it cannot be found. - - - - Gets the domain-hint associated with an identity. - - Identity for which to compute the domain-hint. - The domain hint for the identity, or null if it cannot be found. - - - - Get the display name for the signed-in user, from the . - - Claims about the user/account. - A string containing the display name for the user, as determined by Azure AD (v1.0) and Microsoft identity platform (v2.0) tokens, - or null if the claims cannot be found. - See https://docs.microsoft.com/azure/active-directory/develop/id-tokens#payload-claims. - - - - Gets the user flow ID associated with the . - - The from which to retrieve the user flow ID. - User flow ID of the identity, or null if it cannot be found. - - - - Gets the Home Object ID associated with the . - - The from which to retrieve the sub claim. - Home Object ID (sub) of the identity, or null if it cannot be found. - - - - Gets the Home Tenant ID associated with the . - - The from which to retrieve the sub claim. - Home Tenant ID (sub) of the identity, or null if it cannot be found. - - - - Gets the NameIdentifierId associated with the . - - The from which to retrieve the NameIdentifierId claim. - Name identifier ID of the identity, or null if it cannot be found. - - - - EventIds for Logging. - - - - + + + + Microsoft.Identity.Web + + + + + Extension methods for . + + + + + Creates the from the values found + in an . + + The instance. + A built from . + + + + Extension methods related to App Services authentication (Easy Auth). + + + + + Add authentication with App Services. + + Authentication builder. + The builder, to chain commands. + + + + Default values related to AppServiceAuthentication handler. + + + + + The default value used for AppServiceAuthenticationOptions.AuthenticationScheme. + + + + + App service authentication handler. + + + + + Constructor for the AppServiceAuthenticationHandler. + Note the parameters are required by the base class. + + App service authentication options. + Logger factory. + URL encoder. + System clock. + + + + + + + Information about the App Services configuration on the host. + + + + + Is App Services authentication enabled?. + + + + + Logout URL for App Services Auth web sites. + + + + + ClientID of the App Services Auth web site. + + + + + Client secret of the App Services Auth web site. + + + + + Issuer of the App Services Auth web site. + + + + + Get headers from environment to help debugging App Services authentication. + + + + + Get the ID token from the headers sent by App services authentication. + + Headers. + The ID Token. + + + + Get the IDP from the headers sent by App services authentication. + + Headers. + The IDP. + + + + Get the user claims from the headers and environment variables. + + Headers. + User claims. + + + + Options for Azure App Services authentication. + + + + + Implementation of ITokenAcquisition for App Services authentication (EasyAuth). + + + + + Please call GetOrCreateApplication instead of accessing this field directly. + + + + + Constructor of the AppServicesAuthenticationTokenAcquisition. + + The App token cache provider. + Access to the HttpContext of the request. + HTTP client factory. + + + + + + + + + + + + + + + + + + + + + + + + + Filter used on a controller action to trigger incremental consent. + + + The following controller action will trigger. + + [AuthorizeForScopes(Scopes = new[] {"Mail.Send"})] + public async Task<IActionResult> SendEmail() + { + } + + + + + + Scopes to request. + + + + + Key section on the configuration file that holds the scope value. + + + + + Azure AD B2C user flow. + + + + + Allows specifying an AuthenticationScheme if OpenIdConnect is not the default challenge scheme. + + + + + Handles the . + + Context provided by ASP.NET Core. + + + + Finds an MsalUiRequiredException in one of the inner exceptions. + + Exception from which we look for an MsalUiRequiredException. + The MsalUiRequiredException if there is one, null, otherwise. + + + + Extensions for . + + + + + Enables an Azure Function to act as/expose a protected web API, enabling bearer token authentication. Calling this method from your Azure function validates the token and exposes the identity of the user or app on behalf of which your function is called, in the HttpContext.User member, where your function can make use of it. + + The current HTTP Context, such as req.HttpContext. + A task indicating success or failure. In case of failure . + + + + Azure SDK token credential based on the ITokenAcquisition service. + + + + + Constructor from an ITokenAcquisition service. + + Token acquisition. + + + + + + + + + + Extension methods to send CCS headers. + + + + + Sets the CCS routing hint. + + Builder type. + Builder. + Claims principal for the user. + The builder to chain. + + + + Description of a certificate. + + + + + Creates a certificate description from a certificate (by code). + + Certificate. + A certificate description. + + + + Creates a certificate description from Key Vault. + + The Key Vault URL. + The name of the certificate in Key Vault. + A certificate description. + + + + Creates a certificate description from a Base64 encoded value. + + Base64 encoded certificate value. + A certificate description. + + + + Creates a certificate description from path on disk. + + Path where to find the certificate file. + Certificate password. + A certificate description. + + + + Creates a certificate description from a thumbprint and store location (Certificate Manager on Windows, for instance). + + Certificate thumbprint. + Store location where to find the certificate. + Store name where to find the certificate. + A certificate description. + + + + Creates a certificate description from a thumbprint and store location (Certificate Manager on Windows, for instance). + + Certificate thumbprint. + Store location where to find the certificate. + Store name where to find the certificate. + A certificate description. + + + + Creates a certificate description from a certificate distinguished name (such as CN=name) + and store location (Certificate Manager on Windows, for instance). + + Certificate distinguished named. + Store location where to find the certificate. + Store name where to find the certificate. + A certificate description. + + + + Type of the source of the certificate. + + + + + Container in which to find the certificate. + + If equals , then + the container is the Key Vault base URL. + If equals , then + this value is not used. + If equals , then + this value is the path on disk where to find the certificate. + If equals , + or , then + this value is the path to the certificate in the cert store, for instance CurrentUser/My. + + + + + + URL of the Key Vault, for instance https://msidentitywebsamples.vault.azure.net. + + + + + Certificate store path, for instance "CurrentUser/My". + + This property should only be used in conjunction with DistinguishedName or Thumbprint. + + + + Certificate distinguished name. + + + + + Name of the certificate in Key Vault. + + + + + Certificate thumbprint. + + + + + Path on disk to the certificate. + + + + + Path on disk to the certificate password. + + + + + Base64 encoded certificate value. + + + + + Defines where and how to import the private key of an X.509 certificate. + + + + + Reference to the certificate or value. + + + If equals , then + the reference is the name of the certificate in Key Vault (maybe the version?). + If equals , then + this value is the base 64 encoded certificate itself. + If equals , then + this value is the password to access the certificate (if needed). + If equals , + this value is the distinguished name. + If equals , + this value is the thumbprint. + + + + + The certificate, either provided directly in code + or loaded from the description. + + + + + Source for a certificate. + + + + + Certificate itself. + + + + + From an Azure Key Vault. + + + + + Base64 encoded string directly from the configuration. + + + + + From local path on disk. + + + + + From the certificate store, described by its thumbprint. + + + + + From the certificate store, described by its distinguished name. + + + + + Certificate Loader. + Only use when loading a certificate from a daemon application, or an ASP NET app, using MSAL .NET directly. + For an ASP NET Core app, Microsoft Identity Web will handle the certificate loading for you. + + IConfidentialClientApplication app; + ICertificateLoader certificateLoader = new DefaultCertificateLoader(); + certificateLoader.LoadIfNeeded(config.CertificateDescription); + + app = ConfidentialClientApplicationBuilder.Create(config.ClientId) + .WithCertificate(config.CertificateDescription.Certificate) + .WithAuthority(new Uri(config.Authority)) + .Build(); + + + + + + User assigned managed identity client ID (as opposed to system assigned managed identity) + See https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-portal. + + + + + Load the certificate from the description, if needed. + + Description of the certificate. + + + + Load a certificate from Key Vault, including the private key. + + URL of Key Vault. + Name of the certificate. + Defines where and how to import the private key of an X.509 certificate. + An certificate. + This code is inspired by Heath Stewart's code in: + https://github.com/heaths/azsdk-sample-getcert/blob/master/Program.cs#L46-L82. + + + + + Find a certificate by criteria. + + + + + Interface to implement loading of a certificate. + Only use when loading a certificate from a daemon application, or an ASP NET app, using MSAL .NET directly. + For an ASP NET Core app, Microsoft Identity Web will handle the certificate loading for you. + + IConfidentialClientApplication app; + ICertificateLoader certificateLoader = new DefaultCertificateLoader(); + certificateLoader.LoadIfNeeded(config.CertificateDescription); + + app = ConfidentialClientApplicationBuilder.Create(config.ClientId) + .WithCertificate(config.CertificateDescription.Certificate) + .WithAuthority(new Uri(config.Authority)) + .Build(); + + + + + + Load the certificate from the description, if needed. + + Description of the certificate. + + + + Extensions for . + + + + + Gets the account identifier for an MSAL.NET account from a . + + Claims principal. + A string corresponding to an account identifier as defined in . + + + + Gets the unique object ID associated with the . + + The from which to retrieve the unique object ID. + This method returns the object ID both in case the developer has enabled or not claims mapping. + Unique object ID of the identity, or null if it cannot be found. + + + + Gets the Tenant ID associated with the . + + The from which to retrieve the tenant ID. + Tenant ID of the identity, or null if it cannot be found. + This method returns the tenant ID both in case the developer has enabled or not claims mapping. + + + + Gets the login-hint associated with a . + + Identity for which to complete the login-hint. + The login hint for the identity, or null if it cannot be found. + + + + Gets the domain-hint associated with an identity. + + Identity for which to compute the domain-hint. + The domain hint for the identity, or null if it cannot be found. + + + + Get the display name for the signed-in user, from the . + + Claims about the user/account. + A string containing the display name for the user, as determined by Azure AD (v1.0) and Microsoft identity platform (v2.0) tokens, + or null if the claims cannot be found. + See https://docs.microsoft.com/azure/active-directory/develop/id-tokens#payload-claims. + + + + Gets the user flow ID associated with the . + + The from which to retrieve the user flow ID. + User flow ID of the identity, or null if it cannot be found. + + + + Gets the Home Object ID associated with the . + + The from which to retrieve the sub claim. + Home Object ID (sub) of the identity, or null if it cannot be found. + + + + Gets the Home Tenant ID associated with the . + + The from which to retrieve the sub claim. + Home Tenant ID (sub) of the identity, or null if it cannot be found. + + + + Gets the NameIdentifierId associated with the . + + The from which to retrieve the NameIdentifierId claim. + Name identifier ID of the identity, or null if it cannot be found. + + + + Factory class to create objects. + + + + + Instantiate a from an account object ID and tenant ID. This can + be useful when the web app subscribes to another service on behalf of the user + and then is called back by a notification where the user is identified by their tenant + ID and object ID (like in Microsoft Graph Web Hooks). + + Tenant ID of the account. + Object ID of the account in this tenant ID. + A containing these two claims. + + + + private async Task GetChangedMessagesAsync(IEnumerable<Notification> notifications) + { + HttpContext.User = ClaimsPrincipalExtension.FromTenantIdAndObjectId(subscription.TenantId, + subscription.UserId); + foreach (var notification in notifications) + { + SubscriptionStore subscription = + subscriptionStore.GetSubscriptionInfo(notification.SubscriptionId); + string accessToken = await tokenAcquisition.GetAccessTokenForUserAsync(scopes); + ...} + } + + + + + + Constants for claim types. + + + + + Name claim: "name". + + + + + Old Object Id claim: http://schemas.microsoft.com/identity/claims/objectidentifier. + + + + + New Object id claim: "oid". + + + + + PreferredUserName: "preferred_username". + + + + + Old TenantId claim: "http://schemas.microsoft.com/identity/claims/tenantid". + + + + + New Tenant Id claim: "tid". + + + + + ClientInfo claim: "client_info". + + + + + UniqueObjectIdentifier: "uid". + Home Object Id. + + + + + UniqueTenantIdentifier: "utid". + Home Tenant Id. + + + + + Older scope claim: "http://schemas.microsoft.com/identity/claims/scope". + + + + + Newer scope claim: "scp". + + + + + New Roles claim = "roles". + + + + + Old Role claim: "http://schemas.microsoft.com/ws/2008/06/identity/claims/role". + + + + + Subject claim: "sub". + + + + + Acr claim: "acr". + + + + + UserFlow claim: "http://schemas.microsoft.com/claims/authnclassreference". + + + + + Tfp claim: "tfp". + + + + + Name Identifier ID claim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier". + + + + + General constants for Microsoft Identity Web. + + + + + LoginHint. + Represents the preferred_username claim in the ID token. + + + + + DomainHint. + Determined by the tenant Id. + + + + + Claims. + Determined from the signed-in user. + + + + + Bearer. + Predominant type of access token used with OAuth 2.0. + + + + + AzureAd. + Configuration section name for AzureAd. + + + + + AzureAdB2C. + Configuration section name for AzureAdB2C. + + + + + Scope. + + + + + Policy for B2C user flows. + The name of the policy to check against a specific user flow. + + + + + Constants related to the error messages. + + + + + Constants related to the log messages. + + + + + Extension class containing cookie policies (work around for same site). + + + + + Handles SameSite cookie issue according to the https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1. + The default list of user agents that disallow "SameSite=None", + was taken from https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/. + + to update. + to chain. + + + + Handles SameSite cookie issue according to the docs: https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1 + The default list of user agents that disallow "SameSite=None", was taken from https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/. + + to update. + If you don't want to use the default user agent list implementation, + the method sent in this parameter will be run against the user agent and if returned true, SameSite value will be set to Unspecified. + The default user agent list used can be found at: https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/. + to chain. + + + + Checks if the specified user agent supports "SameSite=None" cookies. + + Browser user agent. + + Incompatible user agents include: + + Versions of Chrome from Chrome 51 to Chrome 66 (inclusive on both ends). + Versions of UC Browser on Android prior to version 12.13.2. + Versions of Safari and embedded browsers on MacOS 10.14 and all browsers on iOS 12. + + Reference: https://www.chromium.org/updates/same-site/incompatible-clients. + + True, if the user agent does not allow "SameSite=None" cookie; otherwise, false. + + + + Implementation for the downstream web API. + + + + + Constructor. + + Token acquisition service. + Named options provider. + HTTP client. + Configuration options. + + + + + + + + + + + + + Merge the options from configuration and override from caller. + + Named configuration. + Delegate to override the configuration. + + + + Extension methods to support downstream web API services. + + + + + Adds a named downstream web API service related to a specific configuration section. + + Builder. + Name of the configuration for the service. + This is the name used when calling the service from controller/pages. + Configuration. + The builder for chaining. + + + + Adds a named downstream web API service initialized with delegates. + + Builder. + Name of the configuration for the service. + This is the name which will be used when calling the service from controller/pages. + Action to configure the options. + The builder for chaining. + + + + Extensions for the downstream web API. + + + + + Get a strongly typed response from the web API. + + Output type. + The downstream web API. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Path to the API endpoint relative to the base URL specified in the configuration. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + A strongly typed response from the web API. + + + + Calls the web API with an HttpPost, providing strongly typed input and getting + strongly typed output. + + Output type. + Input type. + The downstream web API. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Path to the API endpoint relative to the base URL specified in the configuration. + Input data sent to the API. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + A strongly typed response from the web API. + + + + Calls the web API endpoint with an HttpPut, providing strongly typed input data. + + Input type. + The downstream web API. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Path to the API endpoint relative to the base URL specified in the configuration. + Input data sent to the API. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + The value returned by the downstream web API. + + + + Calls the web API endpoint with an HttpPut, provinding strongly typed input data + and getting back strongly typed data. + + Output type. + Input type. + The downstream web API. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Path to the API endpoint relative to the base URL specified in the configuration. + Input data sent to the API. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + A strongly typed response from the web API. + + + + Call a web API endpoint with an HttpGet, + and return strongly typed data. + + Output type. + The downstream web API. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + The value returned by the downstream web API. + + + + Call a web API with a strongly typed input, with an HttpGet. + + Input type. + The downstream web API. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Input data. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + The value returned by the downstream web API. + + + + Options passed-in to call downstream web APIs. To call Microsoft Graph, see rather + MicrosoftGraphOptions in the Microsoft.Identity.Web.MicrosoftGraph assembly. + + + + + Base URL for the called downstream web API. For instance "https://graph.microsoft.com/beta/".. + + + + + Path relative to the (for instance "me"). + + + + + HTTP method used to call this downstream web API (by default Get). + + + + + Clone the options (to be able to override them). + + A clone of the options. + + + + Return the downstream web API URL. + + URL of the downstream web API. + + + + Clone the options (to be able to override them). + + A clone of the options. + + + + Interface used to call a downstream web API, for instance from controllers. + + + + + Calls the downstream web API for the user, based on a description of the + downstream web API in the configuration. + + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful on platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + HTTP context in the case where is + , , . + An that the application will process. + + + + Calls the downstream web API for the user, based on a description of the + downstream web API in the configuration. + + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful on platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + HTTP context in the case where is + , , . + An that the application will process. + + + + Calls a downstream web API consuming JSON with some data and returns data. + + Input type. + Output type. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Input parameter to the downstream web API. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + The value returned by the downstream web API. + + A list method that returns an IEnumerable<MyItem>>. + + public Task<IEnumerable<MyItem>> GetAsync() + { + return _downstreamWebApi.CallWebApiForUserAsync<object, IEnumerable<MyItem>>( + ServiceName, + null, + options => + { + options.RelativePath = $"api/todolist"; + }); + } + + + Example of editing. + + public Task<MyItem> EditAsync(MyItem myItem) + { + return _downstreamWebApi.CallWebApiForUserAsync<MyItem, MyItem>( + ServiceName, + nyItem, + options => + { + options.HttpMethod = HttpMethod.Patch; + options.RelativePath = $"api/todolist/{myItem.Id}"; + }); + } + + + + + + Calls a downstream web API consuming JSON with some data and returns data. + + Input type. + Output type. + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Input parameter to the downstream web API. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + Overrides the options proposed in the configuration described + by . + [Optional] Claims representing a user. This is useful in platforms like Blazor + or Azure Signal R, where the HttpContext is not available. In other platforms, the library + will find the user from the HttpContext. + The value returned by the downstream web API. + + A list method that returns an IEnumerable<MyItem>>. + + public Task<IEnumerable<MyItem>> GetAsync() + { + return _downstreamWebApi.CallWebApiForUserAsync<object, IEnumerable<MyItem>>( + ServiceName, + null, + options => + { + options.RelativePath = $"api/todolist"; + }); + } + + + Example of editing. + + public Task<MyItem> EditAsync(MyItem myItem) + { + return _downstreamWebApi.CallWebApiForUserAsync<MyItem, MyItem>( + ServiceName, + nyItem, + options => + { + options.HttpMethod = HttpMethod.Patch; + options.RelativePath = $"api/todolist/{myItem.Id}"; + }); + } + + + + + + Calls the downstream web API for the app, with the required scopes. + + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Overrides the options proposed in the configuration described + by . + HTTP content in the case where is + , , . + An that the application will process. + + + + Calls the downstream web API for the app, with the required scopes. + + Name of the service describing the downstream web API. There can + be several configuration named sections mapped to a , + each for one downstream web API. You can pass-in null, but in that case + needs to be set. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + Overrides the options proposed in the configuration described + by . + HTTP content in the case where is + , , . + An that the application will process. + + + + A DelegatingHandler implementation that add an authorization header with a token for the application. + + + + + Initializes a new instance of the class. + + Token acquisition service. + Named options provider. + Name of the service describing the downstream web API. + + + + + + + Base class for Microsoft Identity authentication message handlers. + + + + + Gets the token acquisition service. + + + + + Initializes a new instance of the class. + + Token acquisition service. + Named options provider. + Name of the service describing the downstream web API. + + + + Gets the options for the specified request. + + The request. + The configured options. + + + + Base options passed-in to authenticate with Microsoft Identity. + + + + + Space separated scopes required to call the downstream web API. + For instance "user.read mail.read". + + + + + [Optional] tenant ID. This is used for specific scenarios where + the application needs to call a downstream web API on behalf of a user in several tenants. + It would mostly be used from code, not from the configuration. + + + + + [Optional]. User flow (in the case of a B2C downstream web API). If not + specified, the B2C downstream web API will be called with the default user flow from + . + + + + + Modifies the token acquisition request so that the acquired token is a Proof of Possession token (PoP), + rather than a Bearer token. + PoP tokens are similar to Bearer tokens, but are bound to the HTTP request and to a cryptographic key, + which MSAL can manage. See https://aka.ms/msal-net-pop. + Set to true to enable PoP tokens automatically. + + + + + Options passed-in to create the token acquisition object which calls into MSAL .NET. + + + + + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + + + + + Returns the scopes. + + Scopes. + + + + Extension for IHttpClientBuilder for startup initialization of Microsoft Identity authentication handlers. + + + + + Adds a named Microsoft Identity user authentication message handler related to a specific configuration section. + + Builder. + Name of the configuration for the service. + Configuration. + The builder for chaining. + + + + Adds a named Microsoft Identity user authentication message handler initialized with delegates. + + Builder. + Name of the configuration for the service. + Action to configure the options. + The builder for chaining. + + + + Adds a named Microsoft Identity application authentication message handler related to a specific configuration section. + + Builder. + Name of the configuration for the service. + Configuration. + The builder for chaining. + + + + Adds a named Microsoft Identity application authentication message handler initialized with delegates. + + Builder. + Name of the configuration for the service. + Action to configure the options. + The builder for chaining. + + + + Options passed-in to Microsoft Identity message handlers. + + + + + Clone the options (to be able to override them). + + A clone of the options. + + + + Clone the options (to be able to override them). + + A clone of the options. + + + + A DelegatingHandler implementation that add an authorization header with a token on behalf of the current user. + + + + + Initializes a new instance of the class. + + Token acquisition service. + Named options provider. + Configuration options. + Name of the service describing the downstream web API. + + + + + + + Extension methods. + + + + Determines whether the specified string collection contains any. + The search for. + The string collection. + + true if the specified string collection contains any; otherwise, false. + + + + Keep the validated token associated with the HTTP request. + + HTTP context. + Token to preserve after the token is validated so that + it can be used in the actions. + + + + Get the parsed information about the token used to call the web API. + + HTTP context associated with the current request. + used to call the web API. + + + + Provides access to get or set the current error status. + The default implementation will use TempData and be enabled when run under Development. + + + + + Gets the error message for the current request. + + Current . + The current error message if available. + + + + Sets the error message for the current request. + + Current . + Error message to set. + + + + Gets whether error messages should be displayed. + + + + + Helper methods to handle incremental consent and conditional access in + a web app. + + + + + Can the exception be solved by re-signing-in the user?. + + Exception from which the decision will be made. + Returns true if the issue can be solved by signing-in + the user, and false, otherwise. + + + + Build authentication properties needed for incremental consent. + + Scopes to request. + instance. + User. + Userflow being invoked for AAD B2C. + AuthenticationProperties. + + + + An implementation of IConfigurationRetriever geared towards Azure AD issuers metadata. + + + + Retrieves a populated configuration given an address and an . + Address of the discovery document. + The to use to read the discovery document. + A cancellation token that can be used by other objects or threads to receive notice of cancellation. . + + A that, when completed, returns from the configuration. + + address - Azure AD Issuer metadata address URL is required + or retriever - No metadata document retriever is provided. + + + + Model class to hold information parsed from the Azure AD issuer endpoint. + + + + + Issuer associated with the OIDC endpoint. + + + + + Interface for the token acquisition service (encapsulating MSAL.NET). + + + + + Typically used from an ASP.NET Core web app or web API controller. This method gets an access token + for a downstream API on behalf of the user account for which the claims are provided in the + member of the controller's parameter. + + Scopes to request for the downstream API to call. + Enables to override the tenant/account for the same identity. This is useful in the + cases where a given account is guest in other tenants, and you want to acquire tokens for a specific tenant. + Azure AD B2C UserFlow to target. + Optional claims principal representing the user. If not provided, will use the signed-in + user (in a web app), or the user for which the token was received (in a web API) + cases where a given account is guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest in. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An access token to call on behalf of the user, the downstream API characterized by its scopes. + + + + Typically used from an ASP.NET Core web app or web API controller. This method gets an access token + for a downstream API on behalf of the user account for which the claims are provided in the + member of the controller's parameter. + + Scopes to request for the downstream API to call. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + Enables to override the tenant/account for the same identity. This is useful in the + cases where a given account is guest in other tenants, and you want to acquire tokens for a specific tenant. + Azure AD B2C UserFlow to target. + Optional claims principal representing the user. If not provided, will use the signed-in + user (in a web app), or the user for which the token was received (in a web API) + cases where a given account is guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest in. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An access token to call on behalf of the user, the downstream API characterized by its scopes. + + + + Typically used from an ASP.NET Core web app or web API controller. This method gets an access token + for a downstream API on behalf of the user account for which the claims are provided in the + member of the controller's parameter. + + Scopes to request for the downstream API to call. + Enables to override the tenant/account for the same identity. This is useful in the + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant. + Azure AD B2C UserFlow to target. + Optional claims principal representing the user. If not provided, will use the signed-in + user (in a web app), or the user for which the token was received (in a web API) + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest in. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An to call on behalf of the user, the downstream API characterized by its scopes. + + + + Typically used from an ASP.NET Core web app or web API controller. This method gets an access token + for a downstream API on behalf of the user account for which the claims are provided in the + member of the controller's parameter. + + Scopes to request for the downstream API to call. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web APIs. + Enables to override the tenant/account for the same identity. This is useful in the + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant. + Azure AD B2C UserFlow to target. + Optional claims principal representing the user. If not provided, will use the signed-in + user (in a web app), or the user for which the token was received (in a web API) + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest in. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An to call on behalf of the user, the downstream API characterized by its scopes. + + + + Acquires a token from the authority configured in the app, for the confidential client itself (not on behalf of a user) + using the client credentials flow. See https://aka.ms/msal-net-client-credentials. + + The scope requested to access a protected API. For this flow (client credentials), the scope + should be of the form "{ResourceIdUri/.default}" for instance https://management.azure.net/.default or, for Microsoft + Graph, https://graph.microsoft.com/.default as the requested scopes are defined statically with the application registration + in the portal, cannot be overridden in the application, as you can request a token for only one resource at a time (use + several calls to get tokens for other resources). + Enables overriding of the tenant/account for the same identity. This is useful in the + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An access token for the app itself, based on its scopes. + + + + Acquires a token from the authority configured in the app, for the confidential client itself (not on behalf of a user) + using the client credentials flow. See https://aka.ms/msal-net-client-credentials. + + The scope requested to access a protected API. For this flow (client credentials), the scope + should be of the form "{ResourceIdUri/.default}" for instance https://management.azure.net/.default or, for Microsoft + Graph, https://graph.microsoft.com/.default as the requested scopes are defined statically with the application registration + in the portal, cannot be overridden in the application, as you can request a token for only one resource at a time (use + several calls to get tokens for other resources). + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + Enables overriding of the tenant/account for the same identity. This is useful in the + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An access token for the app itself, based on its scopes. + + + + Acquires an authentication result from the authority configured in the app, for the confidential client itself (not on behalf of a user) + using the client credentials flow. See https://aka.ms/msal-net-client-credentials. + + The scope requested to access a protected API. For this flow (client credentials), the scope + should be of the form "{ResourceIdUri/.default}" for instance https://management.azure.net/.default or, for Microsoft + Graph, https://graph.microsoft.com/.default as the requested scopes are defined statically with the application registration + in the portal, and cannot be overridden in the application, as you can request a token for only one resource at a time (use + several calls to get tokens for other resources). + Enables overriding of the tenant/account for the same identity. This is useful + for multi tenant apps or daemons. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An authentication result for the app itself, based on its scopes. + + + + Acquires an authentication result from the authority configured in the app, for the confidential client itself (not on behalf of a user) + using the client credentials flow. See https://aka.ms/msal-net-client-credentials. + + The scope requested to access a protected API. For this flow (client credentials), the scope + should be of the form "{ResourceIdUri/.default}" for instance https://management.azure.net/.default or, for Microsoft + Graph, https://graph.microsoft.com/.default as the requested scopes are defined statically with the application registration + in the portal, and cannot be overridden in the application, as you can request a token for only one resource at a time (use + several calls to get tokens for other resources). + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + Enables overriding of the tenant/account for the same identity. This is useful + for multi tenant apps or daemons. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An authentication result for the app itself, based on its scopes. + + + + Used in web APIs (which therefore cannot have an interaction with the user). + Replies to the client through the HttpResponse by sending a 403 (forbidden) and populating wwwAuthenticateHeaders so that + the client can trigger an interaction with the user so the user can consent to more scopes. + + Scopes to consent to. + triggering the challenge. + The to update. + + + + Used in web APIs (which therefore cannot have an interaction with the user). + Replies to the client through the HttpResponse by sending a 403 (forbidden) and populating wwwAuthenticateHeaders so that + the client can trigger an interaction with the user so the user can consent to more scopes. + + Scopes to consent to. + triggering the challenge. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + The to update. + + + + Get the effective authentication scheme based on the context. + + Proposed authentication scheme. + Effective authenticationScheme which is the authentication scheme + if it's not null, or otherwise OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + + + + Used in web APIs (which therefore cannot have an interaction with the user). + Replies to the client through the HttpResponse by sending a 403 (forbidden) and populating wwwAuthenticateHeaders so that + the client can trigger an interaction with the user so the user can consent to more scopes. + + Scopes to consent to. + triggering the challenge. + The to update. + A representing the asynchronous operation. + + + + Interface for the internal operations of token acquisition service (encapsulating MSAL.NET). + + + + + In a web app, adds, to the MSAL.NET cache, the account of the user authenticating to the web app, when the authorization code is received (after the user + signed-in and consented) + An On-behalf-of token contained in the is added to the cache, so that it can then be used to acquire another token on-behalf-of the + same user in order to call to downstream APIs. + + The context used when an 'AuthorizationCode' is received over the OpenIdConnect protocol. + Scopes to request. + Authentication scheme to use. + A that represents a completed add to cache operation. + + From the configuration of the Authentication of the ASP.NET Core web API: + OpenIdConnectOptions options; + + Subscribe to the authorization code received event: + + options.Events = new OpenIdConnectEvents(); + options.Events.OnAuthorizationCodeReceived = OnAuthorizationCodeReceived; + } + + + And then in the OnAuthorizationCodeRecieved method, call : + + private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) + { + var tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>(); + await _tokenAcquisition.AddAccountToCacheFromAuthorizationCode(context, new string[] { "user.read" }); + } + + + + + + Removes the account associated with context.HttpContext.User from the MSAL.NET cache. + + RedirectContext passed-in to a + OpenID Connect event. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web APIs. + A that represents a completed remove from cache operation. + + + + EventIds for Logging. + + + + + Options for configuring authentication using Azure Active Directory. It has both AAD and B2C configuration attributes. + Merges the MicrosoftIdentityWebOptions and the ConfidentialClientApplicationOptions. + + + + + Base class for web app and web API Microsoft Identity authentication + builders. + + + + + Constructor. + + The services being configured. + Optional configuration section. + + + + The services being configured. + + + + + Configuration section from which to bind options. + + It can be null if the configuration happens with delegates + rather than configuration. + + + + Extensions for IServerSideBlazorBuilder for startup initialization of web APIs. + + + + + Add the incremental consent and conditional access handler for Blazor + server side pages. + + Service side blazor builder. + The builder. + + + + Add the incremental consent and conditional access handler for + web app pages, Razor pages, controllers, views, etc... + + Service collection. + The service collection. + + + + Handler for Blazor specific APIs to handle incremental consent + and conditional access. + + + + + Initializes a new instance of the class. + + Service provider to get the HttpContextAccessor for the current HttpContext, when available. + + + + Boolean to determine if server is Blazor. + + + + + Current user. + + + + + Base URI to use in forming the redirect. + + + + + For Blazor/Razor pages to process the exception from + a user challenge. + + Exception. + + + + Forces the user to consent to specific scopes and perform + Conditional Access to get specific claims. Use on a Razor/Blazor + page or controller to proactively ensure the scopes and/or claims + before acquiring a token. The other mechanism + ensures claims and scopes requested by Azure AD after a failed token acquisition attempt. + See https://aka.ms/ms-id-web/ca_incremental-consent for details. + + Scopes to request. + Claims to ensure. + Userflow being invoked for AAD B2C. + + + + Options for configuring authentication using Azure Active Directory. It has both AAD and B2C configuration attributes. + + + + + Gets or sets the Azure Active Directory instance, e.g. "https://login.microsoftonline.com". + + + + + Gets or sets the tenant ID. + + + + + Gets or sets the domain of the Azure Active Directory tenant, e.g. contoso.onmicrosoft.com. + + + + + Gets or sets the edit profile user flow name for B2C, e.g. b2c_1_edit_profile. + + + + + Gets or sets the sign up or sign in user flow name for B2C, e.g. b2c_1_susi. + + + + + Gets or sets the reset password user flow name for B2C, e.g. B2C_1_password_reset. + + + + + Gets the default user flow (which is signUpsignIn). + + + + + Enables legacy ADAL cache serialization and deserialization. + Performance improvements when working with MSAL only apps. + Set to true if you have a shared cache with ADAL apps. + + The default is false. + + + + Is considered B2C if the attribute SignUpSignInPolicyId is defined. + + + + + Is considered to have client credentials if the attribute ClientCertificates + or ClientSecret is defined. + + + + + Description of the certificates used to prove the identity of the web app or web API. + For the moment only the first certificate is considered. + + An example in the appsetting.json: + + "ClientCertificates": [ + { + "SourceType": "StoreWithDistinguishedName", + "CertificateStorePath": "CurrentUser/My", + "CertificateDistinguishedName": "CN=WebAppCallingWebApiCert" + } + ] + + See also https://aka.ms/ms-id-web-certificates. + + + + + Description of the certificates used to decrypt an encrypted token in a web API. + For the moment only the first certificate is considered. + + An example in the appsetting.json: + + "TokenDecryptionCertificates": [ + { + "SourceType": "StoreWithDistinguishedName", + "CertificateStorePath": "CurrentUser/My", + "CertificateDistinguishedName": "CN=WebAppCallingWebApiCert" + } + ] + + See also https://aka.ms/ms-id-web-certificates. + + + + + Specifies if the x5c claim (public key of the certificate) should be sent to the STS. + Sending the x5c enables application developers to achieve easy certificate rollover in Azure AD: + this method will send the public certificate to Azure AD along with the token request, + so that Azure AD can use it to validate the subject name based on a trusted issuer policy. + This saves the application admin from the need to explicitly manage the certificate rollover + (either via portal or PowerShell/CLI operation). For details see https://aka.ms/msal-net-sni. + + The default is false. + + + + Daemon applications can validate a token based on roles, or using the ACL-based authorization + pattern to control tokens without a roles claim. If using ACL-based authorization, + Microsoft Identity Web will not throw if roles or scopes are not in the Claims. + For details see https://aka.ms/ms-identity-web/daemon-ACL. + + The default is false. + + + + Used, when deployed to Azure, to specify explicitly a user assigned managed identity. + See https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-to-manage-ua-identity-portal. + + + + + Microsoft Identity Web specific exception class for + use in Blazor or Razor pages to process the user challenge. + Handles the . + + + + + Exception thrown by MSAL when a user challenge is encountered. + + + + + Scopes to request. + + + + + Specified userflow. + + + + + Handles the user challenge for Blazor or Razor pages. + + Exception thrown by MSAL when a user challenge is encountered. + Scopes to request. + Userflow used in B2C. + + + + Generic class that validates token issuer from the provided Azure AD authority. + + + + + Validate the issuer for multi-tenant applications of various audiences (Work and School accounts, or Work and School accounts + + Personal accounts). + + Issuer to validate (will be tenanted). + Received security token. + Token validation parameters. + The issuer is considered as valid if it has the same HTTP scheme and authority as the + authority from the configuration file, has a tenant ID, and optionally v2.0 (this web API + accepts both V1 and V2 tokens). + The issuer if it's valid, or otherwise SecurityTokenInvalidIssuerException is thrown. + if is null. + if is null. + if the issuer is invalid. + + + Gets the tenant ID from a token. + A JWT token. + A string containing the tenant ID, if found or . + Only and are acceptable types. + + + + Interface implemented by diagnostics for the JWT Bearer middleware. + + + + + Called to subscribe to . + + JWT Bearer events. + The events (for chaining). + + + + Diagnostics used in the OpenID Connect middleware + (used in web apps). + + + + + Method to subscribe to . + + OpenID Connect events. + + + + Diagnostics for the JwtBearer middleware (used in web APIs). + + + + + Constructor for a . This constructor + is used by dependency injection. + + Logger. + + + + Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. + + + + + Invoked when a protocol message is first received. + + + + + Invoked after the security token has passed validation and a ClaimsIdentity has been generated. + + + + + Invoked before a challenge is sent back to the caller. + + + + + Subscribes to all the JwtBearer events, to help debugging, while + preserving the previous handlers (which are called). + + Events to subscribe to. + for chaining. + + + + Factory class for creating the IssuerValidator per authority. + + + + + Initializes a new instance of the class. + + Options passed-in to create the AadIssuerValidator object. + HttpClientFactory. + + + + Gets an for an authority. + + The authority to create the validator for, e.g. https://login.microsoftonline.com/. + A for the aadAuthority. + if is null or empty. + + + + Diagnostics used in the OpenID Connect middleware + (used in web apps). + + + + + Constructor of the , used + by dependency injection. + + Logger used to log the diagnostics. + + + + Invoked before redirecting to the identity provider to authenticate. This can + be used to set ProtocolMessage.State that will be persisted through the authentication + process. The ProtocolMessage can also be used to add or customize parameters + sent to the identity provider. + + + + + Invoked when a protocol message is first received. + + + + + Invoked after security token validation if an authorization code is present + in the protocol message. + + + + + Invoked after "authorization code" is redeemed for tokens at the token endpoint. + + + + + Invoked when an IdToken has been validated and produced an AuthenticationTicket. + + + + + Invoked when user information is retrieved from the UserInfoEndpoint. + + + + + Invoked if exceptions are thrown during request processing. The exceptions will + be re-thrown after this event unless suppressed. + + + + + Invoked when a request is received on the RemoteSignOutPath. + + + + + Invoked before redirecting to the identity provider to sign out. + + + + + Invoked before redirecting to the Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions.SignedOutRedirectUri + at the end of a remote sign-out flow. + + + + + Subscribes to all the OpenIdConnect events, to help debugging, while + preserving the previous handlers (which are called). + + Events to subscribe to. + + + + Generic class that registers the token audience from the provided Azure AD authority. + + + + + Default validation of the audience: + - when registering an Azure AD web API in the app registration portal (and adding a scope) + the default App ID URI generated by the portal is api://{clientID} + - However, the audience (aud) of the token acquired to access this web API is different depending + on the "accepted access token version" for the web API: + - if accepted token version is 1.0, the audience provided in the token + by the Microsoft identity platform (formerly Azure AD v2.0) endpoint is: api://{ClientID} + - if the accepted token version is 2.0, the audience provided by Azure AD v2.0 in the token + is {CliendID} + When getting an access token for an Azure AD B2C web API the audience in the token is + api://{ClientID}. + + When web API developers don't provide the "Audience" in the configuration, Microsoft.Identity.Web + considers that this is the default App ID URI as explained above. When developer provides the + "Audience" member, it's available in the TokenValidationParameter.ValidAudience. + + Audiences in the security token. + Security token from which to validate the audiences. + Token validation parameters. + True if the token is valid; false, otherwise. + + + + This attribute is used on a controller, pages, or controller actions + to declare (and validate) the scopes required by a web API. These scopes can be declared + in two ways: hardcoding them, or declaring them in the configuration. Depending on your + choice, use either one or the other of the constructors. + For details, see https://aka.ms/ms-id-web/required-scope-attribute. + + + + + Fully qualified name of the configuration key containing the required scopes (separated + by spaces). + + + If the appsettings.json file contains a section named "AzureAd", in which + a property named "Scopes" contains the required scopes, the attribute on the + controller/page/action to protect should be set to the following: + + [RequiredScope(RequiredScopesConfigurationKey="AzureAd:Scopes")] + + + + + + Verifies that the web API is called with the right scopes. + If the token obtained for this API is on behalf of the authenticated user does not have + any of these in its scope claim, the + method updates the HTTP response providing a status code 403 (Forbidden) + and writes to the response body a message telling which scopes are expected in the token. + + Scopes accepted by this web API. + When the scopes don't match, the response is a 403 (Forbidden), + because the user is authenticated (hence not 401), but not authorized. + + Add the following attribute on the controller/page/action to protect: + + + [RequiredScope("access_as_user")] + + + and + if you want to express the required scopes from the configuration. + + + + Default constructor, to be used along with the + property when you want to get the scopes to validate from the configuration, instead + of hardcoding them in the code. + + + + + If the authenticated user does not have any of these , the + method updates the HTTP response providing a status code 403 (Forbidden) + and writes to the response body a message telling which scopes are expected in the token. + + Scopes accepted by this web API. + When the scopes don't match, the response is a 403 (Forbidden), + because the user is authenticated (hence not 401), but not authorized. + + + + Extension class providing the extension methods for that + can be used in web APIs to validate the roles in controller actions. + + + + + When applied to an , verifies that the application + has the expected roles. + + HttpContext (from the controller). + Roles accepted by this web API. + When the roles don't match, the response is a 403 (Forbidden), + because the app does not have the expected roles. + + + + Extension class providing the extension + methods for that + can be used in web APIs to validate scopes in controller actions. + We recommend using instead the RequiredScope Attribute on the controller, the page or the action. + See https://aka.ms/ms-id-web/required-scope-attribute. + + + + + When applied to an , verifies that the user authenticated in the + web API has any of the accepted scopes. + If there is no authenticated user, the response is a 401 (Unauthenticated). + If the authenticated user does not have any of these , the + method updates the HTTP response providing a status code 403 (Forbidden) + and writes to the response body a message telling which scopes are expected in the token. + We recommend using instead the RequiredScope Attribute on the controller, the page or the action. + See https://aka.ms/ms-id-web/required-scope-attribute. + + HttpContext (from the controller). + Scopes accepted by this web API. + + + + Options passed-in to create the AadIssuerValidator object. + + + + + Sets the name of the HttpClient to get from the IHttpClientFactory for use with the configuration manager. + Needed when customizing the client such as configuring a proxy. + + + + + Extensions for IServiceCollection for startup initialization of web APIs. + + + + + Add the token acquisition service. + + Service collection. + Specifies if an instance of should be a singleton. + The service collection. + + This method is typically called from the ConfigureServices(IServiceCollection services) in Startup.cs. + Note that the implementation of the token cache can be chosen separately. + + + // Token acquisition service and its cache implementation as a session cache + services.AddTokenAcquisition() + .AddDistributedMemoryCache() + .AddSession() + .AddSessionBasedTokenCache(); + + + + + + An implementation of that uses to track error messages. + + + + + Token acquisition service. + + + LoggingMessage class for TokenAcquisition. + + + + + Please call GetOrBuildConfidentialClientApplication instead of accessing this field directly. + + + + + Constructor of the TokenAcquisition service. This requires the Azure AD Options to + configure the confidential client application and a token cache provider. + This constructor is called by ASP.NET Core dependency injection. + + The App token cache provider. + Access to the HttpContext of the request. + Configuration options. + HTTP client factory. + Logger. + Service provider. + + + + Scopes which are already requested by MSAL.NET. They should not be re-requested;. + + + + + Meta-tenant identifiers which are not allowed in client credentials. + + + + + This handler is executed after the authorization code is received (once the user signs-in and consents) during the + authorization code flow in a web app. + It uses the code to request an access token from the Microsoft identity platform and caches the tokens and an entry about the signed-in user's account in the MSAL's token cache. + The access token (and refresh token) provided in the , once added to the cache, are then used to acquire more tokens using the + on-behalf-of flow for the signed-in user's account, + in order to call to downstream APIs. + + The context used when an 'AuthorizationCode' is received over the OpenIdConnect protocol. + scopes to request access to. + Authentication scheme to use (by default, OpenIdConnectDefaults.AuthenticationScheme). + + From the configuration of the Authentication of the ASP.NET Core web API: + OpenIdConnectOptions options; + + Subscribe to the authorization code received event: + + options.Events = new OpenIdConnectEvents(); + options.Events.OnAuthorizationCodeReceived = OnAuthorizationCodeReceived; + } + + + And then in the OnAuthorizationCodeRecieved method, call : + + private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) + { + var tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>(); + await _tokenAcquisition.AddAccountToCacheFromAuthorizationCode(context, new string[] { "user.read" }); + } + + + + + + Typically used from a web app or web API controller, this method retrieves an access token + for a downstream API using; + 1) the token cache (for web apps and web APIs) if a token exists in the cache + 2) or the on-behalf-of flow + in web APIs, for the user account that is ascertained from claims provided in the + instance of the current HttpContext. + + Scopes to request for the downstream API to call. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web APIs. + Enables overriding of the tenant/account for the same identity. This is useful in the + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest. + Azure AD B2C user flow to target. + Optional claims principal representing the user. If not provided, will use the signed-in + user (in a web app), or the user for which the token was received (in a web API) + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest. + Options passed-in to create the token acquisition options object which calls into MSAL .NET. + An access token to call the downstream API and populated with this downstream API's scopes. + Calling this method from a web API supposes that you have previously called, + in a method called by JwtBearerOptions.Events.OnTokenValidated, the HttpContextExtensions.StoreTokenUsedToCallWebAPI method + passing the validated token (as a JwtSecurityToken). Calling it from a web app supposes that + you have previously called AddAccountToCacheFromAuthorizationCodeAsync from a method called by + OpenIdConnectOptions.Events.OnAuthorizationCodeReceived. + + + + Acquires an authentication result from the authority configured in the app, for the confidential client itself (not on behalf of a user) + using the client credentials flow. See https://aka.ms/msal-net-client-credentials. + + The scope requested to access a protected API. For this flow (client credentials), the scope + should be of the form "{ResourceIdUri/.default}" for instance https://management.azure.net/.default or, for Microsoft + Graph, https://graph.microsoft.com/.default as the requested scopes are defined statically with the application registration + in the portal, and cannot be overridden in the application, as you can request a token for only one resource at a time (use + several calls to get tokens for other resources). + AuthenticationScheme to use. + Enables overriding of the tenant/account for the same identity. This is useful + for multi tenant apps or daemons. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An authentication result for the app itself, based on its scopes. + + + + Acquires a token from the authority configured in the app, for the confidential client itself (not on behalf of a user) + using the client credentials flow. See https://aka.ms/msal-net-client-credentials. + + The scope requested to access a protected API. For this flow (client credentials), the scope + should be of the form "{ResourceIdUri/.default}" for instance https://management.azure.net/.default or, for Microsoft + Graph, https://graph.microsoft.com/.default as the requested scopes are defined statically with the application registration + in the portal, and cannot be overridden in the application, as you can request a token for only one resource at a time (use + several calls to get tokens for other resources). + AuthenticationScheme to use. + Enables overriding of the tenant/account for the same identity. This is useful + for multi tenant apps or daemons. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An access token for the app itself, based on its scopes. + + + + Typically used from a web app or web API controller, this method retrieves an access token + for a downstream API using; + 1) the token cache (for web apps and web APIs) if a token exists in the cache + 2) or the on-behalf-of flow + in web APIs, for the user account that is ascertained from the claims provided in the + instance of the current HttpContext. + + Scopes to request for the downstream API to call. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + Enables overriding of the tenant/account for the same identity. This is useful in the + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant. + Azure AD B2C user flow to target. + Optional claims principal representing the user. If not provided, will use the signed-in + user (in a web app), or the user for which the token was received (in a web API) + cases where a given account is a guest in other tenants, and you want to acquire tokens for a specific tenant. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + An access token to call the downstream API and populated with this downstream API's scopes. + Calling this method from a web API supposes that you have previously called, + in a method called by JwtBearerOptions.Events.OnTokenValidated, the HttpContextExtensions.StoreTokenUsedToCallWebAPI method + passing the validated token (as a JwtSecurityToken). Calling it from a web app supposes that + you have previously called AddAccountToCacheFromAuthorizationCodeAsync from a method called by + OpenIdConnectOptions.Events.OnAuthorizationCodeReceived. + + + + Used in web APIs (no user interaction). + Replies to the client through the HTTP response by sending a 403 (forbidden) and populating the 'WWW-Authenticate' header so that + the client, in turn, can trigger a user interaction so that the user consents to more scopes. + + Scopes to consent to. + The that triggered the challenge. + The to update. + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + + + + Used in web APIs (no user interaction). + Replies to the client through the HTTP response by sending a 403 (forbidden) and populating the 'WWW-Authenticate' header so that + the client, in turn, can trigger a user interaction so that the user consents to more scopes. + + Scopes to consent to. + The that triggered the challenge. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + The to update. + + + + Removes the account associated with context.HttpContext.User from the MSAL.NET cache. + + RedirectContext passed-in to a + OpenID Connect event. + Authentication scheme. If null, will use OpenIdConnectDefault.AuthenticationScheme + if called from a web app, and JwtBearerDefault.AuthenticationScheme if called from a web API. + A that represents a completed account removal operation. + + + + + + + Creates an MSAL confidential client application. + + + + + Gets an access token for a downstream API on behalf of the user described by its claimsPrincipal. + + . + Claims principal for the user on behalf of whom to get a token. + Scopes for the downstream API to call. + (optional) Authority based on a specific tenant for which to acquire a token to access the scopes + on behalf of the user described in the claimsPrincipal. + Merged options. + Azure AD B2C user flow to target. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + + + + Gets an access token for a downstream API on behalf of the user whose account is passed as an argument. + + . + User IAccount for which to acquire a token. + See . + Scopes for the downstream API to call. + Authority based on a specific tenant for which to acquire a token to access the scopes + on behalf of the user. + Merged options. + Azure AD B2C user flow. + Options passed-in to create the token acquisition object which calls into MSAL .NET. + + + + Logger for handling MSAL exceptions in TokenAcquisition. + + ILogger. + Specific log message from TokenAcquisition. + Exception from MSAL.NET. + + + + Logger for handling information specific to MSAL in token acquisition. + + ILogger. + durationTotalInMs. + durationInHttpInMs. + durationInCacheInMs. + cache or IDP. + correlationId. + Exception from MSAL.NET. + + + + Options passed-in to create the token acquisition object which calls into MSAL .NET. + + + + + Sets the correlation id to be used in the authentication request + to the /token endpoint. + + + + + Sets Extra Query Parameters for the query string in the HTTP authentication request. + + + + + A string with one or multiple claims to request. + Normally used with Conditional Access. + + + + + Specifies if the token request will ignore the access token in the token cache + and will attempt to acquire a new access token. + If true, the request will ignore the token cache. The default is false. + Use this option with care and only when needed, for instance, if you know that conditional access policies have changed, + for it induces performance degradation, as the token cache is not utilized. + + + + + Modifies the token acquisition request so that the acquired token is a Proof of Possession token (PoP), + rather than a Bearer token. + PoP tokens are similar to Bearer tokens, but are bound to the HTTP request and to a cryptographic key, + which MSAL can manage. See https://aka.ms/msal-net-pop. + + + + + Cancellation token to be used when calling the token acquisition methods. + + + + + Clone the options (to be able to override them). + + A clone of the options. + + + + Set of properties that the token cache serialization implementations might use to optimize the cache. + + + + + CancellationToken enabling cooperative cancellation between threads, thread pool, or Task objects. + + + + + Suggested cache expiry based on the in-coming token. Use to optimize cache eviction + with the app token cache. + + + + + Extension class used to add distributed token cache serializer to MSAL. + See https://aka.ms/ms-id-web/token-cache-serialization for details. + + + + Adds the .NET Core distributed cache based app token cache to the service collection. + The services collection to add to. + A to chain. + + + + An implementation of the token cache for both Confidential and Public clients backed by a Distributed Cache. + The Distributed Cache (L2), by default creates a Memory Cache (L1), for faster look up, resulting in a two level cache. + + https://aka.ms/msal-net-token-cache-serialization + + LoggingMessage class for MsalDistributedTokenCacheAdapter. + + + + + .NET Core Memory cache. + + + + + MSAL distributed token cache options. + + + + + Initializes a new instance of the class. + + Distributed cache instance to use. + Options for the token cache. + MsalDistributedTokenCacheAdapter logger. + Service provider. Can be null, in which case the token cache + will not be encrypted. See https://aka.ms/ms-id-web/token-cache-encryption. + + + + Removes a specific token cache, described by its cache key + from the distributed cache. + + Key of the cache to remove. + A that completes when key removal has completed. + + + + Removes a specific token cache, described by its cache key + from the distributed cache. + + Key of the cache to remove. + Hints for the cache serialization implementation optimization. + A that completes when key removal has completed. + + + + Read a specific token cache, described by its cache key, from the + distributed cache. + + Key of the cache item to retrieve. + Read blob representing a token cache for the cache key + (account or app). + + + + Read a specific token cache, described by its cache key, from the + distributed cache. + + Key of the cache item to retrieve. + Hints for the cache serialization implementation optimization. + Read blob representing a token cache for the cache key + (account or app). + + + + Writes a token cache blob to the serialization cache (by key). + + Cache key. + blob to write. + A that completes when a write operation has completed. + + + + Writes a token cache blob to the serialization cache (by key). + + Cache key. + blob to write. + Hints for the cache serialization implementation optimization. + A that completes when a write operation has completed. + + + + LoggingMessage class for MsalDistributedTokenCacheAdapter. + + + + + Memory cache remove. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + MSAL.NET cache key. + Cache size in bytes, or 0 if empty. + Exception. + + + + Memory cache remove. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + MSAL.NET cache key. + Exception. + + + + Memory cache count. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + L1 cache count. + Exception. + + + + L2 cache state logging. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + MSAL.NET cache key. + Cache size in bytes, or 0 if empty. + L2 cache retry due to possible connection issue. + Exception. + + + + L2 cache state logging. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + MSAL.NET cache key. + Cache size in bytes, or 0 if empty. + L2 cache retry due to possible connection issue. + Time in milliseconds. + Exception. + + + + L2 cache retry. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + MSAL.NET cache key. + Exception. + + + + L2 cache retry. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + Time in milliseconds. + Exception. + + + + L2 cache error. + + ILogger. + Distributed or Memory. + Cache operation (Read, Write, etc...). + L2 cache retry due to possible connection issue. + Error message. + Exception. + + + + Back propagate L2 to L1. + + ILogger. + Cache size in bytes, or 0 if empty. + Exception. + + + + Options for the MSAL token cache serialization adapter, + which delegates the serialization to the IDistributedCache implementations + available with .NET Core. + + + + + Options of the In Memory (L1) cache. + + + + + Callback offered to the app to be notified when the L2 cache fails. + This way the app is given the possibility to act on the L2 cache, + for instance, in the case of Redis, to reconnect. This is left to the application as it's + the only one that knows about the real implementation of the L2 cache. + The handler should return true if the cache should try again the operation, and + false otherwise. When true is passed and the retry fails, an exception + will be thrown. + + + + + Value more than 0, less than 1, to set the In Memory (L1) cache + expiration time values relative to the Distributed (L2) cache. + Default is 1. + + + + + Should the token cache be encrypted. + + The default is false. + + + + MSAL token cache provider interface. + + + + + Initializes a token cache (which can be a user token cache or an app token cache). + + Token cache for which to initialize the serialization. + A that represents a completed initialization operation. + + + + Initializes a token cache (which can be a user token cache or an app token cache). + + Token cache for which to initialize the serialization. + + + + Clear the user token cache. + + HomeAccountId for a user account in the cache. + A that represents a completed clear operation. + + + + Extension class used to add an in-memory token cache serializer to MSAL. + + + + Adds both the app and per-user in-memory token caches. + The services collection to add to. + the services (for chaining). + + + + MSAL's in-memory token cache options. + + + + Initializes a new instance of the class. + By default, the sliding expiration is set for 14 days. + + + + Gets or sets the value of the duration after which the cache entry will expire unless it's used + This is the duration the tokens are kept in memory cache. + In production, a higher value, up-to 90 days is recommended. + + + The AbsoluteExpirationRelativeToNow value. + + + + + An implementation of token cache for both Confidential and Public clients backed by MemoryCache. + + https://aka.ms/msal-net-token-cache-serialization + + + + .NET Core Memory cache. + + + + + MSAL memory token cache options. + + + + + Constructor. + + serialization cache. + Memory cache options. + + + + Removes a token cache identified by its key, from the serialization + cache. + + token cache key. + A that completes when key removal has completed. + + + + Reads a blob from the serialization cache (identified by its key). + + Token cache key. + Read Bytes. + + + + Writes a token cache blob to the serialization cache (identified by its key). + + Token cache key. + Bytes to write. + A that completes when a write operation has completed. + + + + Writes a token cache blob to the serialization cache (identified by its key). + + Token cache key. + Bytes to write. + Hints for the cache serialization implementation optimization. + A that completes when a write operation has completed. + + + + Token cache provider with default implementation. + + + + + + Constructor. + + Service provider. Can be null, in which case the token cache + will not be encrypted. See https://aka.ms/ms-id-web/token-cache-encryption. + + + + Initializes the token cache serialization. + + Token cache to serialize/deserialize. + + + + Initializes the token cache serialization. + + Token cache to serialize/deserialize. + A that represents a completed initialization operation. + + + + Raised AFTER MSAL added the new token in its in-memory copy of the cache. + This notification is called every time MSAL accesses the cache, not just when a write takes place: + If MSAL's current operation resulted in a cache change, the property TokenCacheNotificationArgs.HasStateChanged will be set to true. + If that is the case, we call the TokenCache.SerializeMsalV3() to get a binary blob representing the latest cache content – and persist it. + + Contains parameters used by the MSAL call accessing the cache. + + + + If you want to ensure that no concurrent write takes place, use this notification to place a lock on the entry. + + Token cache notification arguments. + A that represents a completed operation. + + + + Clear the cache. + + HomeAccountId for a user account in the cache. + A that represents a completed clear operation. + + + + Method to be implemented by concrete cache serializers to write the cache bytes. + + Cache key. + Bytes to write. + A that represents a completed write operation. + + + + Method to be overridden by concrete cache serializers to write the cache bytes. + + Cache key. + Bytes to write. + Hints for the cache serialization implementation optimization. + A that represents a completed write operation. + + + + Method to be implemented by concrete cache serializers to Read the cache bytes. + + Cache key. + Read bytes. + + + + Method to be overridden by concrete cache serializers to Read the cache bytes. + + Cache key. + Hints for the cache serialization implementation optimization. + Read bytes. + + + + Method to be implemented by concrete cache serializers to remove an entry from the cache. + + Cache key. + A that represents a completed remove key operation. + + + + Method to be overridden by concrete cache serializers to remove an entry from the cache. + + Cache key. + Hints for the cache serialization implementation optimization. + A that represents a completed remove key operation. + + + + An implementation of token cache for confidential clients backed by an HTTP session. + + + For this session cache to work effectively, the ASP.NET Core session has to be configured properly. + The latest guidance is provided at https://docs.microsoft.com/aspnet/core/fundamentals/app-state + + In the method public void ConfigureServices(IServiceCollection services) in Startup.cs, add the following: + + services.AddSession(option => + { + option.Cookie.IsEssential = true; + }); + + In the method public void Configure(IApplicationBuilder app, IHostingEnvironment env) in Startup.cs, add the following: + + app.UseSession(); // Before UseMvc() + + + https://aka.ms/msal-net-token-cache-serialization + + LoggingMessage class for MsalSessionTokenCacheProvider. + + + + + MSAL Token cache provider constructor. + + Session for the current user. + Logger. + + + + Read a blob representing the token cache from its key. + + Key representing the token cache + (account or app). + Read blob. + + + + Read a blob representing the token cache from its key. + + Key representing the token cache + (account or app). + Hints for the cache serialization implementation optimization. + Read blob. + + + + Writes the token cache identified by its key to the serialization mechanism. + + Key for the cache (account ID or app ID). + Blob to write to the cache. + A that completes when a write operation has completed. + + + + Removes a cache described by its key. + + Key of the token cache (user account or app ID). + A that completes when key removal has completed. + + + + LoggingMessage class for MsalSessionTokenCacheProvider. + + + + + Session cache logging. + + ILogger. + /// Cache operation (Read, Write, etc...). + Session Id. + MSAL.NET cache key. + Exception. + + + + Session cache deserialized. + + ILogger. + MSAL.NET cache key. + Session Id. + Exception. + + + + Extension class to add a session token cache serializer to MSAL. + + + + + Adds an HTTP session-based application token cache to the service collection. + + + For this session cache to work effectively the ASP.NET Core session has to be configured properly. + The latest guidance is provided at https://docs.microsoft.com/aspnet/core/fundamentals/app-state. + + In the method public void ConfigureServices(IServiceCollection services) in Startup.cs, add the following: + + services.AddSession(option => + { + option.Cookie.IsEssential = true; + }); + + In the method public void Configure(IApplicationBuilder app, IHostingEnvironment env) in Startup.cs, add the following: + + app.UseSession(); // Before UseMvc() + + Because session token caches are added with scoped lifetime, they should not be used when TokenAcquisition is also used as a singleton (for example, when using Microsoft Graph SDK). + + The services collection to add to. + The service collection. + + + + Adds an HTTP session-based per-user token cache to the service collection. + + + For this session cache to work effectively the ASP.NET Core session has to be configured properly. + The latest guidance is provided at https://docs.microsoft.com/aspnet/core/fundamentals/app-state. + + In the method public void ConfigureServices(IServiceCollection services) in Startup.cs, add the following: + + services.AddSession(option => + { + option.Cookie.IsEssential = true; + }); + + In the method public void Configure(IApplicationBuilder app, IHostingEnvironment env) in Startup.cs, add the following: + + app.UseSession(); // Before UseMvc() + + Because session token caches are added with scoped lifetime, they should not be used when TokenAcquisition is also used as a singleton (for example, when using Microsoft Graph SDK). + + The services collection to add to. + The service collection. + + + + Utility methods used by L1/L2 cache. + + + + + Extension methods to expose a simplified developer experience for + adding token caches to MSAL.NET confidential client applications + in ASP.NET, or .NET Core, or .NET FW. + + + + + Use a token cache and choose the serialization part by adding it to + the services collection and configuring its options. + + The confidential client application. + Confidential client application. + Action that you'll use to add a cache serialization + to the service collection passed as an argument. + The application for chaining. + + + The following code adds a distributed in-memory token cache. + + + app.AddTokenCaches(services => + { + // In memory distributed token cache + // In net472, requires to reference Microsoft.Extensions.Caching.Memory + services.AddDistributedTokenCache(); + services.AddDistributedMemoryCache(); + }); + + + The following code adds a token cache based on REDIS and initializes + its configuration. + + + app.AddTokenCaches(services => + { + services.AddDistributedTokenCache(); + // Redis token cache + // Requires to reference Microsoft.Extensions.Caching.StackExchangeRedis + services.AddStackExchangeRedisCache(options => + { + options.Configuration = "localhost"; + options.InstanceName = "Redis"; + }); + }); + + If using distributed token caches, use AddDistributedTokenCache. + + Don't use this method in ASP.NET Core. Just add use the ConfigureServices method + instead. + + + + Add an in-memory well partitioned token cache to MSAL.NET confidential client + application. Don't use this method in ASP.NET Core: rather use: + services.AddInMemoryTokenCache() in ConfigureServices. + + Confidential client application. + The application for chaining. + + + The following code adds an in-memory token cache. + + + app.AddInMemoryTokenCache(); + + + + Don't use this method in ASP.NET Core. Just add use the ConfigureServices method + instead. + + + + Add a distributed token cache. + + Confidential client application. + Action taking a + and by which you initialize your distributed cache. + The application for chaining. + + The following code adds a token cache based on REDIS and initializes + its configuration. + + + app.AddDistributedTokenCache(services => + { + // Redis token cache + // Requires to reference Microsoft.Extensions.Caching.StackExchangeRedis + services.AddStackExchangeRedisCache(options => + { + options.Configuration = "localhost"; + options.InstanceName = "Redis"; + }); + }); + + + + Don't use this method in ASP.NET Core. Just add use the ConfigureServices method + instead. + + + + Authentication builder for a web API. + + + + + Constructor. + + The services being configured. + Default scheme used for OpenIdConnect. + ACtion called to configure the JwtBearer options. + Action called to configure + the Microsoft identity options. + Configuration section from which to + get parameters. + + + + Protects the web API with Microsoft identity platform (formerly Azure AD v2.0). + + The action to configure . + The authentication builder to chain. + + + + Extensions for for startup initialization of web APIs. + + + + + Protects the web API with Microsoft identity platform (formerly Azure AD v2.0). + This method expects the configuration file will have a section, named "AzureAd" as default, with the necessary settings to initialize authentication options. + + The to which to add this configuration. + The configuration instance. + The configuration section with the necessary settings to initialize authentication options. + The JWT bearer scheme name to be used. By default it uses "Bearer". + + Set to true if you want to debug, or just understand the JWT bearer events. + + The authentication builder to chain. + + + + Protects the web API with Microsoft identity platform (formerly Azure AD v2.0). + This method expects the configuration file will have a section, named "AzureAd" as default, with the necessary settings to initialize authentication options. + + The to which to add this configuration. + The configuration second from which to fill-in the options. + The JWT bearer scheme name to be used. By default it uses "Bearer". + + Set to true if you want to debug, or just understand the JWT bearer events. + + The authentication builder to chain. + + + + Protects the web API with Microsoft identity platform (formerly Azure AD v2.0). + + The to which to add this configuration. + The action to configure . + The action to configure the . + The JWT bearer scheme name to be used. By default it uses "Bearer". + + Set to true if you want to debug, or just understand the JWT bearer events. + The authentication builder to chain. + + + + Builder for web API authentication with configuration. + + + + + Protects the web API with Microsoft identity platform (formerly Azure AD v2.0). + This method expects the configuration file will have a section, named "AzureAd" as default, with the necessary settings to initialize authentication options. + + The authentication builder to chain. + + + + Extension for IServiceCollection for startup initialization of web APIs. + + + + + Protects the web API with Microsoft identity platform (formerly Azure AD v2.0) + This method expects the configuration file will have a section, named "AzureAd" as default, with the necessary settings to initialize authentication options. + + Service collection to which to add authentication. + The Configuration object. + The configuration section with the necessary settings to initialize authentication options. + The JwtBearer scheme name to be used. By default it uses "Bearer". + + Set to true if you want to debug, or just understand the JwtBearer events. + The authentication builder to chain extension methods. + + + + Authentication builder returned by the EnableTokenAcquisitionToCallDownstreamApi methods + enabling you to decide token cache implementations. + + + + + Add in memory token caches. + + to configure. + to configure. + the service collection. + + + + Add distributed token caches. + + the service collection. + + + + Add session token caches. + + the service collection. + + + + Authentication builder specific for Microsoft identity platform. + + + + + Constructor. + + The services being configured. + Default scheme used for OpenIdConnect. + Action called to configure + the Microsoft identity options. + Optional configuration section. + + + + The web app calls a web API. + + Initial scopes. + The builder itself for chaining. + + + + The web app calls a web API. This override enables you to specify the + ConfidentialClientApplicationOptions (from MSAL.NET) programmatically. + + Action to configure the + MSAL.NET confidential client application options. + Initial scopes. + The builder itself for chaining. + + + + Extensions for the for startup initialization. + + + + + Add authentication to a web app with Microsoft identity platform. + This method expects the configuration file will have a section, named "AzureAd" as default, + with the necessary settings to initialize authentication options. + + The to which to add this configuration. + The configuration instance. + The configuration section with the necessary settings to initialize authentication options. + The OpenID Connect scheme name to be used. By default it uses "OpenIdConnect". + The cookie-based scheme name to be used. By default it uses "Cookies". + + Set to true if you want to debug, or just understand the OpenID Connect events. + + The builder for chaining. + + + + Add authentication with Microsoft identity platform. + This method expects the configuration file will have a section, named "AzureAd" as default, with the necessary settings to initialize authentication options. + + The to which to add this configuration. + The configuration section from which to get the options. + The OpenID Connect scheme name to be used. By default it uses "OpenIdConnect". + The cookie-based scheme name to be used. By default it uses "Cookies". + + Set to true if you want to debug, or just understand the OpenID Connect events. + + The authentication builder for chaining. + + + + Add authentication with Microsoft identity platform. + + The to which to add this configuration. + The action to configure . + The action to configure . + The OpenID Connect scheme name to be used. By default it uses "OpenIdConnect". + The cookie-based scheme name to be used. By default it uses "Cookies". + + Set to true if you want to debug, or just understand the OpenID Connect events. + + The authentication builder for chaining. + + + + Add authentication with Microsoft identity platform. + + The to which to add this configuration. + The action to configure . + The action to configure . + The OpenID Connect scheme name to be used. By default it uses "OpenIdConnect". + The cookie-based scheme name to be used. By default it uses "Cookies". + + Set to true if you want to debug, or just understand the OpenID Connect events. + + Configuration section. + The authentication builder for chaining. + + + + Add authentication with Microsoft identity platform. + + The to which to add this configuration. + The action to configure . + The action to configure . + The OpenID Connect scheme name to be used. By default it uses "OpenIdConnect". + The cookie-based scheme name to be used. By default it uses "Cookies". + + Set to true if you want to debug, or just understand the OpenID Connect events. + + The authentication builder for chaining. + + + + Builder for a Microsoft identity web app authentication where configuration is + available for EnableTokenAcquisitionToCallDownstreamApi. + + + + + Constructor. + + The services being configured. + Default scheme used for OpenIdConnect. + Action called to configure + the Microsoft identity options. + Optional configuration section. + + + + Add support for the web app to acquire tokens to call an API. + + Optional initial scopes to request. + The authentication builder for chaining. + + + + Extension for IServiceCollection for startup initialization. + + + + + Add authentication with Microsoft identity platform. + This method expects the configuration file will have a section, (by default named "AzureAd"), with the necessary settings to + initialize the authentication options. + + Service collection to which to add authentication. + The IConfiguration object. + The name of the configuration section with the necessary + settings to initialize authentication options. + Optional name for the open id connect authentication scheme + (by default OpenIdConnectDefaults.AuthenticationScheme). This can be specified when you want to support + several OpenIdConnect identity providers. + Optional name for the cookie authentication scheme + (by default OpenIdConnectDefaults.AuthenticationScheme). + + Set to true if you want to debug, or just understand the OpenIdConnect events. + + The authentication builder to chain extension methods. + + + diff --git a/tests/Microsoft.Identity.Web.Test/HttpClientBuilderExtensionsTests.cs b/tests/Microsoft.Identity.Web.Test/HttpClientBuilderExtensionsTests.cs new file mode 100644 index 000000000..a30f0d414 --- /dev/null +++ b/tests/Microsoft.Identity.Web.Test/HttpClientBuilderExtensionsTests.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; + +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.Identity.Web.Test.Common; + +using Xunit; + +namespace Microsoft.Identity.Web.Test +{ + public class HttpClientBuilderExtensionsTests + { + private const string HttpClientName = "test-client"; + private const string ServiceName = "test-service"; + + private readonly IConfigurationSection _configSection; + + public HttpClientBuilderExtensionsTests() + { + _configSection = GetConfigSection(ServiceName); + } + + private IConfigurationSection GetConfigSection(string key) + { + var builder = new ConfigurationBuilder(); + builder.AddInMemoryCollection( + new Dictionary() + { + { $"{key}:Scopes", TestConstants.Scopes }, + { $"{key}:Tenant", TestConstants.TenantIdAsGuid }, + { $"{key}:UserFlow", TestConstants.B2CSignUpSignInUserFlow }, + { $"{key}:IsProofOfPossessionRequest", "false" }, + { $"{key}:AuthenticationScheme", JwtBearerDefaults.AuthenticationScheme }, + }); + + return builder.Build().GetSection(key); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void AddMicrosoftIdentityAuthenticationHandler_WithConfiguration(bool useApp) + { + // arrange + var services = new ServiceCollection(); + + // act + if (useApp) + { + services.AddHttpClient(HttpClientName) + .AddMicrosoftIdentityAppAuthenticationHandler(ServiceName, _configSection); + } + else + { + services.AddHttpClient(HttpClientName) + .AddMicrosoftIdentityUserAuthenticationHandler(ServiceName, _configSection); + } + + // assert + Assert.Contains(services, s => s.ServiceType == typeof(IConfigureOptions)); + + var provider = services.BuildServiceProvider(); + var options = provider.GetRequiredService>(); + + Assert.Equal(TestConstants.Scopes, options.Get(ServiceName).Scopes); + Assert.Equal(TestConstants.TenantIdAsGuid, options.Get(ServiceName).Tenant); + Assert.Equal(TestConstants.B2CSignUpSignInUserFlow, options.Get(ServiceName).UserFlow); + Assert.False(options.Get(ServiceName).IsProofOfPossessionRequest); + Assert.Equal(JwtBearerDefaults.AuthenticationScheme, options.Get(ServiceName).AuthenticationScheme); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void AddMicrosoftIdentityAuthenticationHandler_WithOptions(bool useApp) + { + // arrange + var services = new ServiceCollection(); + Action configureOptions = options => + { + options.Scopes = TestConstants.GraphScopes; + options.Tenant = TestConstants.TenantIdAsGuid; + options.UserFlow = TestConstants.B2CResetPasswordUserFlow; + options.IsProofOfPossessionRequest = true; + options.AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme; + }; + + // act + if (useApp) + { + services.AddHttpClient(HttpClientName) + .AddMicrosoftIdentityAppAuthenticationHandler(ServiceName, configureOptions); + } + else + { + services.AddHttpClient(HttpClientName) + .AddMicrosoftIdentityUserAuthenticationHandler(ServiceName, configureOptions); + } + + // assert + Assert.Contains(services, s => s.ServiceType == typeof(IConfigureOptions)); + + var provider = services.BuildServiceProvider(); + var options = provider.GetRequiredService>(); + + Assert.Equal(TestConstants.GraphScopes, options.Get(ServiceName).Scopes); + Assert.Equal(TestConstants.TenantIdAsGuid, options.Get(ServiceName).Tenant); + Assert.Equal(TestConstants.B2CResetPasswordUserFlow, options.Get(ServiceName).UserFlow); + Assert.True(options.Get(ServiceName).IsProofOfPossessionRequest); + Assert.Equal(JwtBearerDefaults.AuthenticationScheme, options.Get(ServiceName).AuthenticationScheme); + } + } +} diff --git a/tests/Microsoft.Identity.Web.Test/MicrosoftIdentityAuthenticationMessageHandlerTests.cs b/tests/Microsoft.Identity.Web.Test/MicrosoftIdentityAuthenticationMessageHandlerTests.cs new file mode 100644 index 000000000..a167c684f --- /dev/null +++ b/tests/Microsoft.Identity.Web.Test/MicrosoftIdentityAuthenticationMessageHandlerTests.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.Identity.Client; +using Microsoft.Identity.Web.Test.Common; + +using NSubstitute; + +using Xunit; + +namespace Microsoft.Identity.Web.Test +{ + public class MicrosoftIdentityAuthenticationMessageHandlerTests + { + private const string HttpClientName = "test-client"; + + private readonly AuthenticationResult _authenticationResult; + private readonly MockHttpMessageHandler _mockedMessageHandler; + private readonly MicrosoftIdentityAuthenticationMessageHandlerOptions _handlerOptions; + private readonly MicrosoftIdentityOptions _identityOptions; + + public MicrosoftIdentityAuthenticationMessageHandlerTests() + { + _authenticationResult = GetAuthenticationResult(); + _mockedMessageHandler = new MockHttpMessageHandler(); + _handlerOptions = new MicrosoftIdentityAuthenticationMessageHandlerOptions + { + AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme, + IsProofOfPossessionRequest = false, + Scopes = TestConstants.Scopes, + Tenant = TestConstants.TenantIdAsGuid, + TokenAcquisitionOptions = new TokenAcquisitionOptions(), + UserFlow = TestConstants.B2CSignUpSignInUserFlow, + }; + _identityOptions = new MicrosoftIdentityOptions(); + } + + private AuthenticationResult GetAuthenticationResult() + { + return new AuthenticationResult( + "token", + false, + "id", + DateTimeOffset.UtcNow.AddMinutes(1), + DateTimeOffset.UtcNow.AddMinutes(2), + TestConstants.TenantIdAsGuid, + null, + "id", + Enumerable.Empty(), + Guid.NewGuid()); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task MicrosoftIdentityAuthenticationMessageHandler_Adds_AuthorizationHeader(bool useApp) + { + // arrange + var tokenAcquisition = Substitute.For(); + + var options = Substitute.For>(); + options.CurrentValue.Returns(_handlerOptions); + + var services = new ServiceCollection(); + var builder = services.AddHttpClient(HttpClientName) + .ConfigurePrimaryHttpMessageHandler(() => _mockedMessageHandler); + + if (useApp) + { + tokenAcquisition.GetAuthenticationResultForAppAsync(default, default, default, default) + .ReturnsForAnyArgs(_authenticationResult); + + builder.AddHttpMessageHandler(() => new MicrosoftIdentityAppAuthenticationMessageHandler(tokenAcquisition, options)); + } + else + { + tokenAcquisition.GetAuthenticationResultForUserAsync(default, default, default, default, default, default) + .ReturnsForAnyArgs(_authenticationResult); + + var identityOptions = Substitute.For>(); + identityOptions.Get(string.Empty).Returns(_identityOptions); + + builder.AddHttpMessageHandler(() => new MicrosoftIdentityUserAuthenticationMessageHandler(tokenAcquisition, options, identityOptions)); + } + + var provider = services.BuildServiceProvider(); + var factory = provider.GetRequiredService(); + + var client = factory.CreateClient(HttpClientName); + using var request = new HttpRequestMessage(HttpMethod.Get, TestConstants.GraphBaseUrlBeta); + + // act + var response = await client.SendAsync(request).ConfigureAwait(false); + + // assert + if (useApp) + { + await tokenAcquisition.Received().GetAuthenticationResultForAppAsync( + _handlerOptions.Scopes, + _handlerOptions.AuthenticationScheme, + _handlerOptions.Tenant, + Arg.Any() /* options are cloned */) + .ConfigureAwait(false); + } + else + { + await tokenAcquisition.Received().GetAuthenticationResultForUserAsync( + Arg.Is(scopes => scopes.SequenceEqual(_handlerOptions.GetScopes())), + authenticationScheme: _handlerOptions.AuthenticationScheme, + tenantId: _handlerOptions.Tenant, + userFlow: _handlerOptions.UserFlow, + tokenAcquisitionOptions: Arg.Any() /* options are cloned */) + .ConfigureAwait(false); + } + + Assert.True(_mockedMessageHandler.Requests[0].Headers.Contains(Constants.Authorization)); + Assert.Equal($"Bearer {_authenticationResult.AccessToken}", _mockedMessageHandler.Requests[0].Headers.GetValues(Constants.Authorization).ElementAt(0)); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task MicrosoftIdentityAuthenticationMessageHandler_Replaces_AuthorizationHeader(bool useApp) + { + // arrange + var tokenAcquisition = Substitute.For(); + + var options = Substitute.For>(); + options.CurrentValue.Returns(_handlerOptions); + + var services = new ServiceCollection(); + var builder = services.AddHttpClient(HttpClientName) + .ConfigurePrimaryHttpMessageHandler(() => _mockedMessageHandler); + + if (useApp) + { + tokenAcquisition.GetAuthenticationResultForAppAsync(default, default, default, default) + .ReturnsForAnyArgs(_authenticationResult); + + builder.AddHttpMessageHandler(() => new MicrosoftIdentityAppAuthenticationMessageHandler(tokenAcquisition, options)); + } + else + { + tokenAcquisition.GetAuthenticationResultForUserAsync(default, default, default, default, default, default) + .ReturnsForAnyArgs(_authenticationResult); + + var identityOptions = Substitute.For>(); + identityOptions.Get(string.Empty).Returns(_identityOptions); + + builder.AddHttpMessageHandler(() => new MicrosoftIdentityUserAuthenticationMessageHandler(tokenAcquisition, options, identityOptions)); + } + + var provider = services.BuildServiceProvider(); + var factory = provider.GetRequiredService(); + + var client = factory.CreateClient(HttpClientName); + using var request = new HttpRequestMessage(HttpMethod.Get, TestConstants.GraphBaseUrlBeta); + request.Headers.Add(Constants.Authorization, "auth"); + + // act + var response = await client.SendAsync(request).ConfigureAwait(false); + + // assert + Assert.True(_mockedMessageHandler.Requests[0].Headers.Contains(Constants.Authorization)); + Assert.Equal($"Bearer {_authenticationResult.AccessToken}", _mockedMessageHandler.Requests[0].Headers.GetValues(Constants.Authorization).ElementAt(0)); + } + + private class MockHttpMessageHandler : HttpMessageHandler + { + private readonly HttpStatusCode _statusCode; + private readonly string _reason; + private readonly HttpContent _content; + private readonly List _requests = new List(); + + public IReadOnlyList Requests => _requests; + + public MockHttpMessageHandler(HttpStatusCode statusCode = HttpStatusCode.OK, HttpContent content = default, string reason = default) + { + _statusCode = statusCode; + _reason = reason; + _content = content; + } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + _requests.Add(request); + + return Task.FromResult(new HttpResponseMessage + { + StatusCode = _statusCode, + ReasonPhrase = _reason, + Content = _content, + }); + } + } + } +}