diff --git a/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml b/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml index 307de3cc1..57da2c4c8 100644 --- a/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml +++ b/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml @@ -1067,11 +1067,16 @@ - + 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. @@ -1451,6 +1456,17 @@ When the scopes don't match, the response is a 403 (Forbidden), because the user is authenticated (hence not 401), but not authorized. + + + 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. @@ -1670,6 +1686,12 @@ 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 diff --git a/src/Microsoft.Identity.Web/Resource/AadIssuerValidatorOptions.cs b/src/Microsoft.Identity.Web/Resource/AadIssuerValidatorOptions.cs new file mode 100644 index 000000000..d76146bfb --- /dev/null +++ b/src/Microsoft.Identity.Web/Resource/AadIssuerValidatorOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Identity.Web +{ + /// + /// Options passed-in to create the AadIssuerValidator object. + /// + public class AadIssuerValidatorOptions + { + /// + /// 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. + /// + public string? HttpClientName { get; set; } + } +} diff --git a/src/Microsoft.Identity.Web/Resource/MicrosoftIdentityIssuerValidatorFactory.cs b/src/Microsoft.Identity.Web/Resource/MicrosoftIdentityIssuerValidatorFactory.cs index e5374cad3..2f8bec221 100644 --- a/src/Microsoft.Identity.Web/Resource/MicrosoftIdentityIssuerValidatorFactory.cs +++ b/src/Microsoft.Identity.Web/Resource/MicrosoftIdentityIssuerValidatorFactory.cs @@ -5,6 +5,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Net.Http; +using Microsoft.Extensions.Options; using Microsoft.Identity.Web.InstanceDiscovery; using Microsoft.IdentityModel.Protocols; @@ -15,9 +17,30 @@ namespace Microsoft.Identity.Web.Resource /// internal class MicrosoftIdentityIssuerValidatorFactory { + public MicrosoftIdentityIssuerValidatorFactory( + IOptions aadIssuerValidatorOptions, + IHttpClientFactory httpClientFactory) + { + if (aadIssuerValidatorOptions?.Value?.HttpClientName != null) + { + _configManager = + new ConfigurationManager( + Constants.AzureADIssuerMetadataUrl, + new IssuerConfigurationRetriever(), + httpClientFactory.CreateClient(aadIssuerValidatorOptions.Value.HttpClientName)); + } + else + { + _configManager = + new ConfigurationManager( + Constants.AzureADIssuerMetadataUrl, + new IssuerConfigurationRetriever()); + } + } + private readonly IDictionary _issuerValidators = new ConcurrentDictionary(); - private readonly ConfigurationManager _configManager = new ConfigurationManager(Constants.AzureADIssuerMetadataUrl, new IssuerConfigurationRetriever()); + private readonly ConfigurationManager _configManager; /// /// Gets an for an authority. diff --git a/src/Microsoft.Identity.Web/WebApiExtensions/MicrosoftIdentityWebApiAuthenticationBuilderExtensions.cs b/src/Microsoft.Identity.Web/WebApiExtensions/MicrosoftIdentityWebApiAuthenticationBuilderExtensions.cs index c5752d6d4..9eab5d2ff 100644 --- a/src/Microsoft.Identity.Web/WebApiExtensions/MicrosoftIdentityWebApiAuthenticationBuilderExtensions.cs +++ b/src/Microsoft.Identity.Web/WebApiExtensions/MicrosoftIdentityWebApiAuthenticationBuilderExtensions.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using System.ComponentModel; using System.Linq; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -160,6 +159,7 @@ private static void AddMicrosoftIdentityWebApiImplementation( builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpClient(); builder.Services.TryAddSingleton(); + builder.Services.AddOptions(); if (subscribeToJwtBearerMiddlewareDiagnosticsEvents) { diff --git a/tests/Microsoft.Identity.Web.Test/Resource/AadIssuerValidatorTests.cs b/tests/Microsoft.Identity.Web.Test/Resource/AadIssuerValidatorTests.cs index b7d63dc3a..ed6e9b11c 100644 --- a/tests/Microsoft.Identity.Web.Test/Resource/AadIssuerValidatorTests.cs +++ b/tests/Microsoft.Identity.Web.Test/Resource/AadIssuerValidatorTests.cs @@ -4,6 +4,7 @@ using System; using System.Globalization; using System.IdentityModel.Tokens.Jwt; +using System.Net.Http; using System.Security.Claims; using Microsoft.Identity.Web.Resource; using Microsoft.Identity.Web.Test.Common; @@ -17,10 +18,14 @@ namespace Microsoft.Identity.Web.Test.Resource public class AadIssuerValidatorTests { private readonly MicrosoftIdentityIssuerValidatorFactory _issuerValidatorFactory; + private IHttpClientFactory _httpClientFactory; public AadIssuerValidatorTests() { - _issuerValidatorFactory = new MicrosoftIdentityIssuerValidatorFactory(); + _httpClientFactory = new HttpClientFactoryTest(); + _issuerValidatorFactory = new MicrosoftIdentityIssuerValidatorFactory( + null, + _httpClientFactory); } [Fact] diff --git a/tests/Microsoft.Identity.Web.Test/Resource/HttpClientFactoryTest.cs b/tests/Microsoft.Identity.Web.Test/Resource/HttpClientFactoryTest.cs new file mode 100644 index 000000000..67a094e09 --- /dev/null +++ b/tests/Microsoft.Identity.Web.Test/Resource/HttpClientFactoryTest.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; +using System.Net.Http; + +namespace Microsoft.Identity.Web.Test.Resource +{ + public class HttpClientFactoryTest : IHttpClientFactory + { + public Dictionary dictionary = new Dictionary(); + + public HttpClient CreateClient(string name) + { + using SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler(); + socketsHttpHandler.UseProxy = true; + return new HttpClient(socketsHttpHandler); + } + } +} diff --git a/tests/WebAppCallsWebApiCallsGraph/TodoListService/Startup.cs b/tests/WebAppCallsWebApiCallsGraph/TodoListService/Startup.cs index 0d459f6c7..cfc906f16 100644 --- a/tests/WebAppCallsWebApiCallsGraph/TodoListService/Startup.cs +++ b/tests/WebAppCallsWebApiCallsGraph/TodoListService/Startup.cs @@ -30,6 +30,8 @@ public void ConfigureServices(IServiceCollection services) // This flag ensures that the ClaimsIdentity claims collection will be built from the claims in the token // JwtSecurityTokenHandler.DefaultMapInboundClaims = false; + + // Adds Microsoft Identity platform (AAD v2.0) support to protect this Api services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(Configuration, "AzureAd") @@ -37,6 +39,13 @@ public void ConfigureServices(IServiceCollection services) .AddInMemoryTokenCaches(); services.AddControllers(); + + // below code is how customers would use a proxy + //services.Configure(options => { options.HttpClientName = "cats"; }); + //services.AddHttpClient("cats", c => + //{ + // // configure things here + //}); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.