diff --git a/Directory.Build.props b/Directory.Build.props
index e6b33147e..98601fabd 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -87,7 +87,7 @@
4.36.0
4.57.0-preview
3.1.3
- 5.3.0
+ 6.0.0
9.0.0-preview.4.24266.19
9.0.0-preview.4.24267.6
diff --git a/benchmark/TokenAcquisitionBenchmark.cs b/benchmark/TokenAcquisitionBenchmark.cs
index ec657628b..5c369c304 100644
--- a/benchmark/TokenAcquisitionBenchmark.cs
+++ b/benchmark/TokenAcquisitionBenchmark.cs
@@ -5,8 +5,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
-using BenchmarkDotNet.Diagnostics.Windows;
-using BenchmarkDotNet.Diagnostics.Windows.Configs;
namespace Benchmarks
{
@@ -40,7 +38,7 @@ public async Task CreateAuthorizationHeader()
{
// Get the authorization request creator service
IAuthorizationHeaderProvider authorizationHeaderProvider = s_serviceProvider!.GetRequiredService();
- await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default");
+ await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default").ConfigureAwait(false);
}
[Benchmark]
diff --git a/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs b/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
index c4cfe0c73..5551a33b3 100644
--- a/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
+++ b/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
@@ -224,11 +224,11 @@ public Task CallApiForAppAsync(
HttpContent? httpContent;
if (effectiveOptions.Serializer != null)
- {
+ {
httpContent = effectiveOptions.Serializer(input);
- }
- else
- {
+ }
+ else
+ {
// if the input is already an HttpContent, it's used as is, and should already contain a ContentType.
httpContent = input switch
{
@@ -304,15 +304,15 @@ internal async Task CallApiInternalAsync(
CancellationToken cancellationToken = default)
{
// Downstream API URI
- string apiUrl = effectiveOptions.GetApiUrl();
-
+ string apiUrl = effectiveOptions.GetApiUrl();
+
// Create an HTTP request message
using HttpRequestMessage httpRequestMessage = new(
new HttpMethod(effectiveOptions.HttpMethod),
apiUrl);
- await UpdateRequestAsync(httpRequestMessage, content, effectiveOptions, appToken, user, cancellationToken);
-
+ await UpdateRequestAsync(httpRequestMessage, content, effectiveOptions, appToken, user, cancellationToken);
+
using HttpClient client = string.IsNullOrEmpty(serviceName) ? _httpClientFactory.CreateClient() : _httpClientFactory.CreateClient(serviceName);
// Send the HTTP message
@@ -351,26 +351,24 @@ internal async Task UpdateRequestAsync(
httpRequestMessage.Content = content;
}
+ effectiveOptions.RequestAppToken = appToken;
+
// Obtention of the authorization header (except when calling an anonymous endpoint
// which is done by not specifying any scopes
if (effectiveOptions.Scopes != null && effectiveOptions.Scopes.Any())
{
- string authorizationHeader = appToken ?
- await _authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(
- effectiveOptions.Scopes.FirstOrDefault()!,
- effectiveOptions,
- cancellationToken).ConfigureAwait(false) :
- await _authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(
- effectiveOptions.Scopes,
- effectiveOptions,
- user,
- cancellationToken).ConfigureAwait(false);
+ string authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderAsync(
+ effectiveOptions.Scopes,
+ effectiveOptions,
+ user,
+ cancellationToken).ConfigureAwait(false);
+
httpRequestMessage.Headers.Add(Authorization, authorizationHeader);
- }
+ }
else
{
Logger.UnauthenticatedApiCall(_logger, null);
- }
+ }
if (!string.IsNullOrEmpty(effectiveOptions.AcceptHeader))
{
httpRequestMessage.Headers.Accept.ParseAdd(effectiveOptions.AcceptHeader);
diff --git a/src/Microsoft.Identity.Web.GraphServiceClient/GraphAuthenticationProvider.cs b/src/Microsoft.Identity.Web.GraphServiceClient/GraphAuthenticationProvider.cs
index 7c63678e1..a02f96c31 100644
--- a/src/Microsoft.Identity.Web.GraphServiceClient/GraphAuthenticationProvider.cs
+++ b/src/Microsoft.Identity.Web.GraphServiceClient/GraphAuthenticationProvider.cs
@@ -24,9 +24,10 @@ internal class GraphAuthenticationProvider : IAuthenticationProvider
readonly IAuthorizationHeaderProvider _authorizationHeaderProvider;
readonly GraphServiceClientOptions _defaultAuthenticationOptions;
private readonly string[] _graphUris = ["graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn", "canary.graph.microsoft.com", "graph.microsoft-ppe.com"];
+ readonly IEnumerable _defaultGraphScope = ["https://graph.microsoft.com/.default"];
///
- /// Constructor from the authorization header provider.
+ /// Constructor for the authorization header provider.
///
///
///
@@ -86,21 +87,12 @@ public async Task AuthenticateRequestAsync(
// Add the authorization header
if (allowedHostsValidator.IsUrlHostValid(request.URI) && !request.Headers.ContainsKey(AuthorizationHeaderKey))
{
- string authorizationHeader;
- if (authorizationHeaderProviderOptions!.RequestAppToken)
- {
- authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default",
+ string authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderAsync(
+ authorizationHeaderProviderOptions!.RequestAppToken ? _defaultGraphScope : scopes!,
authorizationHeaderProviderOptions,
- cancellationToken);
- }
- else
- {
- authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(
- scopes!,
- authorizationHeaderProviderOptions,
- claimsPrincipal: user,
- cancellationToken);
- }
+ user,
+ cancellationToken).ConfigureAwait(false);
+
request.Headers.Add(AuthorizationHeaderKey, authorizationHeader);
}
}
diff --git a/src/Microsoft.Identity.Web.MicrosoftGraph/TokenAcquisitionAuthenticationProvider.cs b/src/Microsoft.Identity.Web.MicrosoftGraph/TokenAcquisitionAuthenticationProvider.cs
index 4dc92904b..bcf700bbd 100644
--- a/src/Microsoft.Identity.Web.MicrosoftGraph/TokenAcquisitionAuthenticationProvider.cs
+++ b/src/Microsoft.Identity.Web.MicrosoftGraph/TokenAcquisitionAuthenticationProvider.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
using System;
+using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
@@ -16,13 +17,14 @@ namespace Microsoft.Identity.Web
internal class TokenAcquisitionAuthenticationProvider : IAuthenticationProvider
{
public TokenAcquisitionAuthenticationProvider(IAuthorizationHeaderProvider authorizationHeaderProvider, TokenAcquisitionAuthenticationProviderOption options)
- {
+ {
_authorizationHeaderProvider = authorizationHeaderProvider;
_initialOptions = options;
}
private readonly IAuthorizationHeaderProvider _authorizationHeaderProvider;
private readonly TokenAcquisitionAuthenticationProviderOption _initialOptions;
+ private readonly IEnumerable _defaultGraphScope = ["https://graph.microsoft.com/.default"];
///
/// Adds an authorization header to an HttpRequestMessage.
@@ -55,26 +57,17 @@ public async Task AuthenticateRequestAsync(HttpRequestMessage request)
DownstreamApiOptions? downstreamOptions = new DownstreamApiOptions() { BaseUrl = "https://graph.microsoft.com", Scopes = scopes };
downstreamOptions.AcquireTokenOptions.AuthenticationOptionsName = scheme;
downstreamOptions.AcquireTokenOptions.Tenant = tenant;
+ downstreamOptions.RequestAppToken = appOnly;
if (msalAuthProviderOption?.AuthorizationHeaderProviderOptions != null)
{
msalAuthProviderOption.AuthorizationHeaderProviderOptions(downstreamOptions);
}
- string authorizationHeader;
- if (appOnly)
- {
- authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(
- Constants.DefaultGraphScope,
- downstreamOptions).ConfigureAwait(false);
- }
- else
- {
- authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(
- scopes!,
+ string authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderAsync(
+ appOnly ? _defaultGraphScope : scopes!,
downstreamOptions,
- claimsPrincipal: user).ConfigureAwait(false);
- }
+ user).ConfigureAwait(false);
// add or replace authorization header
if (request.Headers.Contains(Constants.Authorization))
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs b/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs
index 151ef8f84..947a44770 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs
@@ -3,9 +3,7 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Security.Claims;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
@@ -29,21 +27,35 @@ public BaseAuthorizationHeaderProvider(IServiceProvider serviceProvider)
// in the public API as it's going to be deprecated in future versions of IdWeb. Here this
// is an implementation detail.
var _tokenAcquisition = serviceProvider.GetRequiredService();
- implementation = new DefaultAuthorizationHeaderProvider(_tokenAcquisition);
+ _headerProvider = new DefaultAuthorizationHeaderProvider(_tokenAcquisition);
}
- private IAuthorizationHeaderProvider implementation;
+ private readonly IAuthorizationHeaderProvider _headerProvider;
///
public virtual Task CreateAuthorizationHeaderForUserAsync(IEnumerable scopes, AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, ClaimsPrincipal? claimsPrincipal = null, CancellationToken cancellationToken = default)
{
- return implementation.CreateAuthorizationHeaderForUserAsync(scopes, authorizationHeaderProviderOptions, claimsPrincipal, cancellationToken);
+ return _headerProvider.CreateAuthorizationHeaderForUserAsync(scopes, authorizationHeaderProviderOptions, claimsPrincipal, cancellationToken);
}
///
public virtual Task CreateAuthorizationHeaderForAppAsync(string scopes, AuthorizationHeaderProviderOptions? downstreamApiOptions = null, CancellationToken cancellationToken = default)
{
- return implementation.CreateAuthorizationHeaderForAppAsync(scopes, downstreamApiOptions, cancellationToken);
+ return _headerProvider.CreateAuthorizationHeaderForAppAsync(scopes, downstreamApiOptions, cancellationToken);
+ }
+
+ ///
+ public virtual Task CreateAuthorizationHeaderAsync(
+ IEnumerable scopes,
+ AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null,
+ ClaimsPrincipal? claimsPrincipal = null,
+ CancellationToken cancellationToken = default)
+ {
+ return _headerProvider.CreateAuthorizationHeaderAsync(
+ scopes,
+ authorizationHeaderProviderOptions,
+ claimsPrincipal,
+ cancellationToken);
}
}
}
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs b/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs
index a630a859f..d8fa44f12 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
@@ -50,6 +51,46 @@ public async Task CreateAuthorizationHeaderForAppAsync(
return result.CreateAuthorizationHeader();
}
+ ///
+ public async Task CreateAuthorizationHeaderAsync(
+ IEnumerable scopes,
+ AuthorizationHeaderProviderOptions? downstreamApiOptions = null,
+ ClaimsPrincipal? claimsPrincipal = null,
+ CancellationToken cancellationToken = default)
+ {
+ Client.AuthenticationResult result;
+
+ // Previously, with the API name we were able to distinguish between app and user token acquisition
+ // This context is missing in the new API, so can we enforce that downstreamApiOptions.RequestAppToken
+ // needs to be set to true to acquire a token for the app. We cannot rely on ClaimsPrincipal as it can be null for user token acquisition.
+ // DevEx Before:
+ // await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default").ConfigureAwait(false);
+ // DevEx with the new API:
+ // await authorizationHeaderProvider.CreateAuthorizationHeaderAsync(
+ // new [] { "https://graph.microsoft.com/.default" },
+ // new AuthorizationHeaderProviderOptions { RequestAppToken = true }).ConfigureAwait(false);
+ if (downstreamApiOptions != null && downstreamApiOptions.RequestAppToken)
+ {
+ result = await _tokenAcquisition.GetAuthenticationResultForAppAsync(
+ scopes.FirstOrDefault()!,
+ downstreamApiOptions?.AcquireTokenOptions.AuthenticationOptionsName,
+ downstreamApiOptions?.AcquireTokenOptions.Tenant,
+ CreateTokenAcquisitionOptionsFromApiOptions(downstreamApiOptions, cancellationToken)).ConfigureAwait(false);
+ return result.CreateAuthorizationHeader();
+ }
+ else
+ {
+ result = await _tokenAcquisition.GetAuthenticationResultForUserAsync(
+ scopes,
+ downstreamApiOptions?.AcquireTokenOptions.AuthenticationOptionsName,
+ downstreamApiOptions?.AcquireTokenOptions.Tenant,
+ downstreamApiOptions?.AcquireTokenOptions.UserFlow,
+ claimsPrincipal,
+ CreateTokenAcquisitionOptionsFromApiOptions(downstreamApiOptions, cancellationToken)).ConfigureAwait(false);
+ return result.CreateAuthorizationHeader();
+ }
+ }
+
private static TokenAcquisitionOptions CreateTokenAcquisitionOptionsFromApiOptions(
AuthorizationHeaderProviderOptions? downstreamApiOptions,
CancellationToken cancellationToken)
diff --git a/tests/E2E Tests/TokenAcquirerTests/TokenAcquirer.cs b/tests/E2E Tests/TokenAcquirerTests/TokenAcquirer.cs
index 361afed5f..51de4a4cb 100644
--- a/tests/E2E Tests/TokenAcquirerTests/TokenAcquirer.cs
+++ b/tests/E2E Tests/TokenAcquirerTests/TokenAcquirer.cs
@@ -4,12 +4,10 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
-using System.Net.Http;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Graph;
@@ -427,6 +425,9 @@ public async Task AcquireTokenWithManagedIdentity_UserAssigned()
// Assert: Make sure we got a token
Assert.False(string.IsNullOrEmpty(result));
+
+ result = await api.CreateAuthorizationHeaderAsync([scope], GetAuthHeaderOptions_ManagedId(baseUrl, clientId));
+ Assert.False(string.IsNullOrEmpty(result));
}
private static AuthorizationHeaderProviderOptions GetAuthHeaderOptions_ManagedId(string baseUrl, string? userAssignedClientId = null)
diff --git a/tests/Microsoft.Identity.Web.Test/BaseAuthorizationHeaderProviderTest.cs b/tests/Microsoft.Identity.Web.Test/BaseAuthorizationHeaderProviderTest.cs
index 5dee70fa5..e6637eeab 100644
--- a/tests/Microsoft.Identity.Web.Test/BaseAuthorizationHeaderProviderTest.cs
+++ b/tests/Microsoft.Identity.Web.Test/BaseAuthorizationHeaderProviderTest.cs
@@ -31,7 +31,7 @@ public CustomAuthorizationHeaderProvider(IServiceProvider serviceProvider) : bas
public override Task CreateAuthorizationHeaderForAppAsync(string scopes, AuthorizationHeaderProviderOptions? downstreamApiOptions = null, CancellationToken cancellationToken = default)
{
if (downstreamApiOptions?.ProtocolScheme == "Custom")
- return Task.FromResult("Custom");
+ return Task.FromResult("CustomHeaderForApp");
else
return base.CreateAuthorizationHeaderForAppAsync(scopes, downstreamApiOptions, cancellationToken);
}
@@ -39,10 +39,20 @@ public override Task CreateAuthorizationHeaderForAppAsync(string scopes,
public override Task CreateAuthorizationHeaderForUserAsync(IEnumerable scopes, AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, ClaimsPrincipal? claimsPrincipal = null, CancellationToken cancellationToken = default)
{
if (authorizationHeaderProviderOptions?.ProtocolScheme == "Custom")
- return Task.FromResult("Custom");
+ return Task.FromResult("CustomHeaderForUser");
else
return base.CreateAuthorizationHeaderForUserAsync(scopes, authorizationHeaderProviderOptions, claimsPrincipal, cancellationToken);
}
+
+ public override Task CreateAuthorizationHeaderAsync(IEnumerable scopes, AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, ClaimsPrincipal? claimsPrincipal = null, CancellationToken cancellationToken = default)
+ {
+ if (claimsPrincipal == null && authorizationHeaderProviderOptions?.ProtocolScheme == "Custom")
+ return Task.FromResult("CustomHeaderForApp");
+ else if (claimsPrincipal != null && authorizationHeaderProviderOptions?.ProtocolScheme == "Custom")
+ return Task.FromResult("CustomHeaderForUser");
+ else
+ return base.CreateAuthorizationHeaderAsync(scopes, authorizationHeaderProviderOptions, claimsPrincipal, cancellationToken);
+ }
}
// Mock for ITokenAcquisition
@@ -106,13 +116,31 @@ public async Task TestBaseAuthorizationHeaderProvider()
var serviceProvider = tokenAcquirerFactory.Build();
IAuthorizationHeaderProvider authorizationHeaderProvider = serviceProvider.GetRequiredService();
+
+ // test acquiring a header on behalf of a user
string result = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(["scope"],
- new AuthorizationHeaderProviderOptions { ProtocolScheme = "Custom" }, null, CancellationToken.None);
- Assert.Equal("Custom", result);
+ new AuthorizationHeaderProviderOptions { ProtocolScheme = "Custom" }, new ClaimsPrincipal(), CancellationToken.None);
+ Assert.Equal("CustomHeaderForUser", result);
result = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(["scope"],
- new AuthorizationHeaderProviderOptions { }, null, CancellationToken.None);
+ new AuthorizationHeaderProviderOptions { }, new ClaimsPrincipal(), CancellationToken.None);
Assert.Equal("Bearer eXY", result);
+
+ result = await authorizationHeaderProvider.CreateAuthorizationHeaderAsync(["scope"],
+ new AuthorizationHeaderProviderOptions { ProtocolScheme = "Custom" }, new ClaimsPrincipal(), CancellationToken.None);
+ Assert.Equal("CustomHeaderForUser", result);
+
+ TokenAcquirerFactory.ResetDefaultInstance(); // Test only
+
+ // test acquiring a header on behalf of an app
+ result = await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("scope",
+ new AuthorizationHeaderProviderOptions { ProtocolScheme = "Custom" }, CancellationToken.None);
+ Assert.Equal("CustomHeaderForApp", result);
+
+ result = await authorizationHeaderProvider.CreateAuthorizationHeaderAsync(["scope"],
+ new AuthorizationHeaderProviderOptions { ProtocolScheme = "Custom" }, null, CancellationToken.None);
+ Assert.Equal("CustomHeaderForApp", result);
+
TokenAcquirerFactory.ResetDefaultInstance(); // Test only
}
}
diff --git a/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/CaeTests.cs b/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/CaeTests.cs
index 8c853cbf9..9a64640ae 100644
--- a/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/CaeTests.cs
+++ b/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/CaeTests.cs
@@ -45,9 +45,9 @@ public async Task DownstreamApi_GetForApp_Retries401WithClaimsResponseOnce()
var appVal = await _downstreamApi.GetForAppAsync("GraphApp");
- await _authorizationHeaderProvider.ReceivedWithAnyArgs(2).CreateAuthorizationHeaderForAppAsync(string.Empty);
- await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderForAppAsync(
- Arg.Any(), Arg.Is(o => o.AcquireTokenOptions.Claims!.Equals(ParsedClaims, StringComparison.Ordinal)));
+ await _authorizationHeaderProvider.ReceivedWithAnyArgs(2).CreateAuthorizationHeaderAsync(Enumerable.Empty());
+ await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderAsync(
+ Arg.Any>(), Arg.Is(o => o.AcquireTokenOptions.Claims!.Equals(ParsedClaims, StringComparison.Ordinal)));
}
[Fact]
@@ -61,8 +61,8 @@ public async Task DownstreamApi_GetForUser_Retries401WithClaimsResponseOnce()
var userVal = await _downstreamApi.GetForUserAsync("GraphUser");
- await _authorizationHeaderProvider.ReceivedWithAnyArgs(2).CreateAuthorizationHeaderForUserAsync(Enumerable.Empty());
- await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderForUserAsync(
+ await _authorizationHeaderProvider.ReceivedWithAnyArgs(2).CreateAuthorizationHeaderAsync(Enumerable.Empty());
+ await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderAsync(
Arg.Any>(), Arg.Is(o => o.AcquireTokenOptions.Claims!.Equals(ParsedClaims, StringComparison.Ordinal)));
}
@@ -77,9 +77,9 @@ public async Task DownstreamApi_GetForApp_DoesntRetrySucessfullResponse()
var appVal = await _downstreamApi.GetForAppAsync("GraphApp");
- await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderForAppAsync(string.Empty);
- await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderForAppAsync(
- Arg.Any(), Arg.Is(o => o.AcquireTokenOptions.Claims == null));
+ await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderAsync(Enumerable.Empty());
+ await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderAsync(
+ Arg.Any>(), Arg.Is(o => o.AcquireTokenOptions.Claims == null));
}
[Fact]
@@ -93,8 +93,8 @@ public async Task DownstreamApi_GetForUser_DoesntRetrySucessfullResponse()
var userVal = await _downstreamApi.GetForUserAsync("GraphUser");
- await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderForUserAsync(Enumerable.Empty());
- await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderForUserAsync(
+ await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderAsync(Enumerable.Empty());
+ await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderAsync(
Arg.Any>(), Arg.Is(o => o.AcquireTokenOptions.Claims == null));
}
@@ -109,9 +109,9 @@ public async Task DownstreamApi_GetForApp_DoesntRetry401WithoutClaimsResponse()
await Assert.ThrowsAsync(() => _downstreamApi.GetForAppAsync("GraphApp"));
- await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderForAppAsync(string.Empty);
- await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderForAppAsync(
- Arg.Any(), Arg.Is(o => o.AcquireTokenOptions.Claims == null));
+ await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderAsync(Enumerable.Empty());
+ await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderAsync(
+ Arg.Any>(), Arg.Is(o => o.AcquireTokenOptions.Claims == null));
}
[Fact]
@@ -125,8 +125,8 @@ public async Task DownstreamApi_GetForUser_DoesntRetry401WithoutClaimsResponse()
await Assert.ThrowsAsync(() => _downstreamApi.GetForUserAsync("GraphUser"));
- await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderForUserAsync(Enumerable.Empty());
- await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderForUserAsync(
+ await _authorizationHeaderProvider.ReceivedWithAnyArgs(1).CreateAuthorizationHeaderAsync(Enumerable.Empty());
+ await _authorizationHeaderProvider.Received().CreateAuthorizationHeaderAsync(
Arg.Any>(), Arg.Is(o => o.AcquireTokenOptions.Claims == null));
}
@@ -135,6 +135,7 @@ private void BuildRequiredServices(string serviceName, Action();
_authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string.Empty).ReturnsForAnyArgs("Bearer eyJhY2Nlc3NfdG9rZW4iOg==");
_authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(Enumerable.Empty()).ReturnsForAnyArgs("Bearer eyJhY2Nlc3NfdG9rZW4iOg==");
+ _authorizationHeaderProvider.CreateAuthorizationHeaderAsync(Enumerable.Empty()).ReturnsForAnyArgs("Bearer eyJhY2Nlc3NfdG9rZW4iOg==");
var httpMessageHandler = new QueueHttpMessageHandler();
diff --git a/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/DownstreamApiTests.cs b/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/DownstreamApiTests.cs
index 3788ece82..dc4818bae 100644
--- a/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/DownstreamApiTests.cs
+++ b/tests/Microsoft.Identity.Web.Test/DownstreamWebApiSupport/DownstreamApiTests.cs
@@ -309,6 +309,11 @@ public Task CreateAuthorizationHeaderForUserAsync(IEnumerable sc
{
return Task.FromResult("Bearer ey");
}
+
+ public Task CreateAuthorizationHeaderAsync(IEnumerable scopes, AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, ClaimsPrincipal? claimsPrincipal = null, CancellationToken cancellationToken = default)
+ {
+ return Task.FromResult("Bearer ey");
+ }
}
}