diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs index 07e28a80d..e3f2d3b25 100644 --- a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs @@ -74,7 +74,9 @@ public async Task CallWebApiForUserAsync( string accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync( effectiveOptions.GetScopes(), effectiveOptions.Tenant, - userflow) + userflow, + user, + effectiveOptions.TokenAcquisitionOptions) .ConfigureAwait(false); HttpResponseMessage response; @@ -175,7 +177,8 @@ public async Task CallWebApiForAppAsync( string accessToken = await _tokenAcquisition.GetAccessTokenForAppAsync( effectiveOptions.Scopes, - effectiveOptions.Tenant) + effectiveOptions.Tenant, + effectiveOptions.TokenAcquisitionOptions) .ConfigureAwait(false); HttpResponseMessage response; diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs index e0d15b37d..85dfe425b 100644 --- a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs +++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApiOptions.cs @@ -46,6 +46,11 @@ public class DownstreamWebApiOptions /// public HttpMethod HttpMethod { get; set; } = HttpMethod.Get; + /// + /// Options passed-in to create the token acquisition object which calls into MSAL .NET. + /// + public TokenAcquisitionOptions TokenAcquisitionOptions { get; set; } = new TokenAcquisitionOptions(); + /// /// Clone the options (to be able to override them). /// @@ -60,6 +65,7 @@ public DownstreamWebApiOptions Clone() Tenant = Tenant, UserFlow = UserFlow, HttpMethod = HttpMethod, + TokenAcquisitionOptions = TokenAcquisitionOptions.Clone(), }; } diff --git a/src/Microsoft.Identity.Web/ITokenAcquisition.cs b/src/Microsoft.Identity.Web/ITokenAcquisition.cs index bed44fed1..b801e24ea 100644 --- a/src/Microsoft.Identity.Web/ITokenAcquisition.cs +++ b/src/Microsoft.Identity.Web/ITokenAcquisition.cs @@ -26,12 +26,14 @@ public interface ITokenAcquisition /// 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. Task GetAccessTokenForUserAsync( IEnumerable scopes, string? tenantId = null, string? userFlow = null, - ClaimsPrincipal? user = null); + ClaimsPrincipal? user = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null); /// /// Typically used from an ASP.NET Core web app or web API controller, this method gets an access token @@ -45,12 +47,14 @@ Task GetAccessTokenForUserAsync( /// 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. Task GetAuthenticationResultForUserAsync( IEnumerable scopes, string? tenantId = null, string? userFlow = null, - ClaimsPrincipal? user = null); + ClaimsPrincipal? user = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null); /// /// Acquires a token from the authority configured in the app, for the confidential client itself (not on behalf of a user) @@ -63,8 +67,12 @@ Task GetAuthenticationResultForUserAsync( /// 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. - Task GetAccessTokenForAppAsync(string scope, string? tenant = null); + Task GetAccessTokenForAppAsync( + string scope, + string? tenant = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null); /// /// Used in web APIs (which therefore cannot have an interaction with the user). diff --git a/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml b/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml index 3e207b08f..08c882bb4 100644 --- a/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml +++ b/src/Microsoft.Identity.Web/Microsoft.Identity.Web.xml @@ -670,6 +670,11 @@ HTTP method used to call this downstream web API (by default Get). + + + Options passed-in to create the token acquisition object which calls into MSAL .NET. + + Clone the options (to be able to override them). @@ -886,7 +891,7 @@ 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 which claims are provided in the @@ -899,9 +904,10 @@ 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 which claims are provided in the @@ -914,9 +920,10 @@ 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. @@ -928,6 +935,7 @@ 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. @@ -1516,7 +1524,7 @@ - + Typically used from a web app or web API controller, this method retrieves an access token for a downstream API using; @@ -1532,6 +1540,7 @@ 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 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 @@ -1539,7 +1548,7 @@ you have previously called AddAccountToCacheFromAuthorizationCodeAsync from a method called by OpenIdConnectOptions.Events.OnAuthorizationCodeReceived. - + 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. @@ -1551,9 +1560,10 @@ 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 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; @@ -1569,6 +1579,7 @@ 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 @@ -1605,7 +1616,7 @@ Creates an MSAL confidential client application. - + Gets an access token for a downstream API on behalf of the user described by its claimsPrincipal. @@ -1615,8 +1626,9 @@ (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. 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. @@ -1627,6 +1639,36 @@ Authority based on a specific tenant for which to acquire a token to access the scopes on behalf of the user. Azure AD B2C user flow. + Options passed-in to create the token acquisition object which calls into 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. + + + + + 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. + + + + + Clone the options (to be able to override them). + + A clone of the options. diff --git a/src/Microsoft.Identity.Web/TokenAcquisition.cs b/src/Microsoft.Identity.Web/TokenAcquisition.cs index b1f21ab57..de0890544 100644 --- a/src/Microsoft.Identity.Web/TokenAcquisition.cs +++ b/src/Microsoft.Identity.Web/TokenAcquisition.cs @@ -31,7 +31,6 @@ internal class TokenAcquisition : ITokenAcquisition, ITokenAcquisitionInternal { private readonly MicrosoftIdentityOptions _microsoftIdentityOptions; private readonly ConfidentialClientApplicationOptions _applicationOptions; - private readonly IMsalTokenCacheProvider _tokenCacheProvider; private IConfidentialClientApplication? _application; @@ -183,8 +182,9 @@ public async Task AddAccountToCacheFromAuthorizationCodeAsync( /// 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), or - /// 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 . + /// 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 @@ -195,7 +195,8 @@ public async Task GetAuthenticationResultForUserAsync( IEnumerable scopes, string? tenant = null, string? userFlow = null, - ClaimsPrincipal? user = null) + ClaimsPrincipal? user = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null) { if (scopes == null) { @@ -214,7 +215,8 @@ public async Task GetAuthenticationResultForUserAsync( authenticationResult = await GetAuthenticationResultForWebApiToCallDownstreamApiAsync( _application, authority, - scopes).ConfigureAwait(false); + scopes, + tokenAcquisitionOptions).ConfigureAwait(false); if (authenticationResult != null) { @@ -252,8 +254,12 @@ public async Task GetAuthenticationResultForUserAsync( /// 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 access token for the app itself, based on its scopes. - public async Task GetAccessTokenForAppAsync(string scope, string? tenant = null) + public async Task GetAccessTokenForAppAsync( + string scope, + string? tenant = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null) { if (string.IsNullOrEmpty(scope)) { @@ -275,12 +281,20 @@ public async Task GetAccessTokenForAppAsync(string scope, string? tenant string authority = CreateAuthorityBasedOnTenantIfProvided(_application, tenant); AuthenticationResult result; - result = await _application + var builder = _application .AcquireTokenForClient(new string[] { scope }.Except(_scopesRequestedByMsal)) .WithSendX5C(_microsoftIdentityOptions.SendX5C) - .WithAuthority(authority) - .ExecuteAsync() - .ConfigureAwait(false); + .WithAuthority(authority); + + if (tokenAcquisitionOptions != null) + { + builder.WithExtraQueryParameters(tokenAcquisitionOptions.ExtraQueryParameters); + builder.WithCorrelationId(tokenAcquisitionOptions.CorrelationId); + builder.WithForceRefresh(tokenAcquisitionOptions.ForceRefresh); + } + + result = await builder.ExecuteAsync() + .ConfigureAwait(false); return result.AccessToken; } @@ -300,6 +314,7 @@ public async Task GetAccessTokenForAppAsync(string scope, string? tenant /// 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 @@ -310,9 +325,16 @@ public async Task GetAccessTokenForUserAsync( IEnumerable scopes, string? tenant = null, string? userFlow = null, - ClaimsPrincipal? user = null) + ClaimsPrincipal? user = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null) { - AuthenticationResult result = await GetAuthenticationResultForUserAsync(scopes, tenant, userFlow, user).ConfigureAwait(false); + AuthenticationResult result = + await GetAuthenticationResultForUserAsync( + scopes, + tenant, + userFlow, + user, + tokenAcquisitionOptions).ConfigureAwait(false); return result.AccessToken; } @@ -492,7 +514,8 @@ private async Task BuildConfidentialClientApplic private async Task GetAuthenticationResultForWebApiToCallDownstreamApiAsync( IConfidentialClientApplication application, string authority, - IEnumerable scopes) + IEnumerable scopes, + TokenAcquisitionOptions? tokenAcquisitionOptions) { try { @@ -505,13 +528,21 @@ private async Task BuildConfidentialClientApplic // In the case the token is a JWE (encrypted token), we use the decrypted token. string tokenUsedToCallTheWebApi = validatedToken.InnerToken == null ? validatedToken.RawData : validatedToken.InnerToken.RawData; - var result = await application - .AcquireTokenOnBehalfOf(scopes.Except(_scopesRequestedByMsal), new UserAssertion(tokenUsedToCallTheWebApi)) + var builder = application + .AcquireTokenOnBehalfOf( + scopes.Except(_scopesRequestedByMsal), + new UserAssertion(tokenUsedToCallTheWebApi)) .WithSendX5C(_microsoftIdentityOptions.SendX5C) - .WithAuthority(authority) - .ExecuteAsync() - .ConfigureAwait(false); - return result; + .WithAuthority(authority); + + if (tokenAcquisitionOptions != null) + { + builder.WithExtraQueryParameters(tokenAcquisitionOptions.ExtraQueryParameters); + builder.WithCorrelationId(tokenAcquisitionOptions.CorrelationId); + } + + return await builder.ExecuteAsync() + .ConfigureAwait(false); } return null; @@ -532,12 +563,14 @@ private async Task BuildConfidentialClientApplic /// (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. /// Azure AD B2C user flow to target. + /// Options passed-in to create the token acquisition object which calls into MSAL .NET. private async Task GetAuthenticationResultForWebAppWithAccountFromCacheAsync( IConfidentialClientApplication application, ClaimsPrincipal? claimsPrincipal, IEnumerable scopes, string? authority, - string? userFlow = null) + string? userFlow = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null) { IAccount? account = null; if (_microsoftIdentityOptions.IsB2C && !string.IsNullOrEmpty(userFlow)) @@ -561,7 +594,9 @@ private async Task GetAuthenticationResultForWebAppWithAcc application, account, scopes, - authority).ConfigureAwait(false); + authority, + userFlow, + tokenAcquisitionOptions).ConfigureAwait(false); } /// @@ -574,43 +609,48 @@ private async Task GetAuthenticationResultForWebAppWithAcc /// Authority based on a specific tenant for which to acquire a token to access the scopes /// on behalf of the user. /// Azure AD B2C user flow. + /// Options passed-in to create the token acquisition object which calls into MSAL .NET. private async Task GetAuthenticationResultForWebAppWithAccountFromCacheAsync( IConfidentialClientApplication application, IAccount? account, IEnumerable scopes, string? authority, - string? userFlow = null) + string? userFlow = null, + TokenAcquisitionOptions? tokenAcquisitionOptions = null) { if (scopes == null) { throw new ArgumentNullException(nameof(scopes)); } - AuthenticationResult result; + var builder = application + .AcquireTokenSilent(scopes.Except(_scopesRequestedByMsal), account) + .WithSendX5C(_microsoftIdentityOptions.SendX5C); + + if (tokenAcquisitionOptions != null) + { + builder.WithExtraQueryParameters(tokenAcquisitionOptions.ExtraQueryParameters); + builder.WithCorrelationId(tokenAcquisitionOptions.CorrelationId); + builder.WithForceRefresh(tokenAcquisitionOptions.ForceRefresh); + } + // Acquire an access token as a B2C authority if (_microsoftIdentityOptions.IsB2C) { string b2cAuthority = application.Authority.Replace( new Uri(application.Authority).PathAndQuery, $"/{ClaimConstants.Tfp}/{_microsoftIdentityOptions.Domain}/{userFlow ?? _microsoftIdentityOptions.DefaultUserFlow}"); - result = await application - .AcquireTokenSilent(scopes.Except(_scopesRequestedByMsal), account) - .WithB2CAuthority(b2cAuthority) - .WithSendX5C(_microsoftIdentityOptions.SendX5C) - .ExecuteAsync() - .ConfigureAwait(false); - - return result; + builder.WithB2CAuthority(b2cAuthority) + .WithSendX5C(_microsoftIdentityOptions.SendX5C); + } + else + { + builder.WithAuthority(authority); } - result = await application - .AcquireTokenSilent(scopes.Except(_scopesRequestedByMsal), account) - .WithAuthority(authority) - .WithSendX5C(_microsoftIdentityOptions.SendX5C) - .ExecuteAsync() - .ConfigureAwait(false); - return result; + return await builder.ExecuteAsync() + .ConfigureAwait(false); } private static bool AcceptedTokenVersionMismatch(MsalUiRequiredException msalServiceException) diff --git a/src/Microsoft.Identity.Web/TokenAcquisitionOptions.cs b/src/Microsoft.Identity.Web/TokenAcquisitionOptions.cs new file mode 100644 index 000000000..1a614644d --- /dev/null +++ b/src/Microsoft.Identity.Web/TokenAcquisitionOptions.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; + +namespace Microsoft.Identity.Web +{ + /// + /// Options passed-in to create the token acquisition object which calls into MSAL .NET. + /// + public class TokenAcquisitionOptions + { + /// + /// Sets the correlation id to be used in the authentication request + /// to the /token endpoint. + /// + public Guid CorrelationId { get; set; } + + /// + /// Sets Extra Query Parameters for the query string in the HTTP authentication request. + /// + public Dictionary? ExtraQueryParameters { get; set; } = null; + + /// + /// 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. + /// + public bool ForceRefresh { get; set; } = false; + + /// + /// Clone the options (to be able to override them). + /// + /// A clone of the options. + public TokenAcquisitionOptions Clone() + { + return new TokenAcquisitionOptions + { + CorrelationId = CorrelationId, + ExtraQueryParameters = ExtraQueryParameters, + ForceRefresh = ForceRefresh, + }; + } + } +} diff --git a/tests/IntegrationTests/IntegrationTestService/Controllers/WeatherForecastController.cs b/tests/IntegrationTests/IntegrationTestService/Controllers/WeatherForecastController.cs index a9a524322..9de5ae45b 100644 --- a/tests/IntegrationTests/IntegrationTestService/Controllers/WeatherForecastController.cs +++ b/tests/IntegrationTests/IntegrationTestService/Controllers/WeatherForecastController.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -54,7 +55,9 @@ public async Task CallDownstreamWebApiGenericAsync() var user = await _downstreamWebApi.CallWebApiForUserAsync( TestConstants.SectionNameCalledApi, null, - options => { options.RelativePath = "me"; }); + options => { + options.RelativePath = "me"; + }); return user.DisplayName; } @@ -65,5 +68,22 @@ public async Task CallMicrosoftGraphAsync() var user = await _graphServiceClient.Me.Request().GetAsync(); return user.DisplayName; } + + [HttpGet(TestConstants.SecurePageCallDownstreamWebApiGenericWithTokenAcquisitionOptions)] + public async Task CallDownstreamWebApiGenericWithTokenAcquisitionOptionsAsync() + { + HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi); + var user = await _downstreamWebApi.CallWebApiForUserAsync( + TestConstants.SectionNameCalledApi, + null, + options => { + options.RelativePath = "me"; + options.TokenAcquisitionOptions.CorrelationId = TestConstants.s_correlationId; + options.TokenAcquisitionOptions.ExtraQueryParameters = new Dictionary() + { { "slice", "testslice" } }; + options.TokenAcquisitionOptions.ForceRefresh = true; + }); + return user.DisplayName; + } } } diff --git a/tests/Microsoft.Identity.Web.Test.Common/TestConstants.cs b/tests/Microsoft.Identity.Web.Test.Common/TestConstants.cs index c7c5c0109..f74cb3c5a 100644 --- a/tests/Microsoft.Identity.Web.Test.Common/TestConstants.cs +++ b/tests/Microsoft.Identity.Web.Test.Common/TestConstants.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Collections.Generic; namespace Microsoft.Identity.Web.Test.Common @@ -126,6 +127,7 @@ public static class TestConstants public const string SecurePageGetTokenAsync = "/SecurePage/GetTokenAsync"; public const string SecurePageCallDownstreamWebApi = "/SecurePage/CallDownstreamWebApiAsync"; public const string SecurePageCallDownstreamWebApiGeneric = "/SecurePage/CallDownstreamWebApiGenericAsync"; + public const string SecurePageCallDownstreamWebApiGenericWithTokenAcquisitionOptions = "/SecurePage/CallDownstreamWebApiGenericWithTokenAcquisitionOptionsAsync"; public const string SecurePageCallMicrosoftGraph = "/SecurePage/CallMicrosoftGraph"; public const string SectionNameCalledApi = "CalledApi"; @@ -137,5 +139,8 @@ public static class TestConstants public const string StaySignedInNoId = "idBtn_Back"; public const string PhotoLabel = "photo"; public const string Headless = "headless"; + + // TokenAcqusitionOptions + public static Guid s_correlationId = new Guid("6347d33d-941a-4c35-9912-a9cf54fb1b3e"); } } diff --git a/tests/Microsoft.Identity.Web.Test.Integration/AcquireTokenForUserIntegrationTests.cs b/tests/Microsoft.Identity.Web.Test.Integration/AcquireTokenForUserIntegrationTests.cs index 66986c808..683f45cdf 100644 --- a/tests/Microsoft.Identity.Web.Test.Integration/AcquireTokenForUserIntegrationTests.cs +++ b/tests/Microsoft.Identity.Web.Test.Integration/AcquireTokenForUserIntegrationTests.cs @@ -10,6 +10,7 @@ using IntegrationTestService; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Graph; using Microsoft.Identity.Client; using Microsoft.Identity.Web.Test.Common; using Microsoft.Identity.Web.Test.LabInfrastructure; @@ -34,6 +35,7 @@ public AcquireTokenForUserIntegrationTests(WebApplicationFactory factor [InlineData(TestConstants.SecurePageCallDownstreamWebApi)] [InlineData(TestConstants.SecurePageCallDownstreamWebApiGeneric)] [InlineData(TestConstants.SecurePageCallMicrosoftGraph)] + [InlineData(TestConstants.SecurePageCallDownstreamWebApiGenericWithTokenAcquisitionOptions)] [InlineData(TestConstants.SecurePageGetTokenAsync, false)] // [InlineData(TestConstants.SecurePageCallDownstreamWebApi, false)] // [InlineData(TestConstants.SecurePageCallDownstreamWebApiGeneric, false)] @@ -79,7 +81,6 @@ public async Task GetTokenForUserAsync( "{0} {1}", Constants.Bearer, result.AccessToken)); - response = await client.SendAsync(httpRequestMessage).ConfigureAwait(false); } diff --git a/tests/Microsoft.Identity.Web.Test/WebAppExtensionsTests.cs b/tests/Microsoft.Identity.Web.Test/WebAppExtensionsTests.cs index 030f716e4..370b872d5 100644 --- a/tests/Microsoft.Identity.Web.Test/WebAppExtensionsTests.cs +++ b/tests/Microsoft.Identity.Web.Test/WebAppExtensionsTests.cs @@ -481,7 +481,7 @@ public void AddDownstreamWebApiOptionsTest(bool useDownstreamWebApiOptions) // Assert properties set var downstreamWebApiOptions = provider.GetRequiredService>(); - IDownstreamWebApi downstreamWebApi = provider.GetRequiredService(); + provider.GetRequiredService(); if (useDownstreamWebApiOptions) {