Skip to content

Commit 90ddea8

Browse files
committed
Finalize tests
1 parent d3bb818 commit 90ddea8

File tree

6 files changed

+110
-10
lines changed

6 files changed

+110
-10
lines changed

tests/E2E Tests/OidcIdPSignedAssertionProviderTests/OidCIdPSignedAssertionProviderExtensibilityTests.cs

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@
22
// Licensed under the MIT License.
33

44
using System;
5+
using System.Collections.Generic;
6+
using System.IdentityModel.Tokens.Jwt;
57
using System.Linq;
8+
using System.Net.Http;
9+
using System.Text.Json;
610
using System.Threading.Tasks;
11+
using Azure.Core;
12+
using Microsoft.Extensions.Configuration;
713
using Microsoft.Extensions.DependencyInjection;
814
using Microsoft.Identity.Abstractions;
915
using Microsoft.Identity.Client;
1016
using Microsoft.Identity.Web;
17+
using Microsoft.Identity.Web.Test.Common;
18+
using Microsoft.Identity.Web.Test.Common.Mocks;
1119
using Xunit.Sdk;
1220

1321

@@ -16,7 +24,7 @@ namespace CustomSignedAssertionProviderTests
1624
public class OidCIdPSignedAssertionProviderExtensibilityTests
1725
{
1826
[Fact]
19-
public async Task UseSignedAssertionFromCustomSignedAssertionProvider()
27+
public async Task CrossCloudFicIntegrationTest()
2028
{
2129
// Arrange
2230
TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
@@ -39,15 +47,86 @@ public async Task UseSignedAssertionFromCustomSignedAssertionProvider()
3947
IServiceProvider serviceProvider = tokenAcquirerFactory.Build();
4048
IAuthorizationHeaderProvider authorizationHeaderProvider = serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
4149

42-
try
50+
// Act
51+
string result = await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default");
52+
53+
// Assert
54+
Assert.NotNull(result);
55+
Assert.StartsWith("Bearer", result, StringComparison.Ordinal);
56+
}
57+
58+
[Fact]
59+
public async Task CrossCloudFicUnitTest()
60+
{
61+
// Arrange
62+
using (MockHttpClientFactory httpFactoryForTest = new MockHttpClientFactory())
4363
{
64+
65+
_ = httpFactoryForTest.AddMockHandler(
66+
MockHttpCreator.CreateInstanceDiscoveryMockHandler());
67+
var credentialRequestHttpHandler = httpFactoryForTest.AddMockHandler(
68+
MockHttpCreator.CreateClientCredentialTokenHandler());
69+
var tokenRequestHttpHandler = httpFactoryForTest.AddMockHandler(
70+
MockHttpCreator.CreateClientCredentialTokenHandler());
71+
72+
// TODO: need to reset the configuration to avoid conflicts with other tests
73+
TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
74+
tokenAcquirerFactory.Services.AddOidcSignedAssertionProvider();
75+
tokenAcquirerFactory.Services.AddSingleton<IHttpClientFactory>(httpFactoryForTest);
76+
77+
tokenAcquirerFactory.Services.Configure<MicrosoftIdentityApplicationOptions>("AzureAd2",
78+
options =>
79+
{
80+
options.Instance = "https://login.microsoftonline.us/";
81+
options.TenantId = "t1";
82+
options.ClientId = "c1";
83+
options.ClientCredentials = [ new CredentialDescription() {
84+
SourceType = CredentialSource.ClientSecret,
85+
ClientSecret = TestConstants.ClientSecret
86+
}];
87+
});
88+
89+
tokenAcquirerFactory.Services.Configure<MicrosoftIdentityApplicationOptions>(options =>
90+
{
91+
options.Instance = "https://login.microsoftonline.com/";
92+
options.TenantId = "t2";
93+
options.ClientId = "c2";
94+
options.ExtraQueryParameters = null;
95+
options.ClientCredentials = [ new CredentialDescription() {
96+
SourceType = CredentialSource.CustomSignedAssertion,
97+
CustomSignedAssertionProviderName = "OidIdpSignedAssertion",
98+
CustomSignedAssertionProviderData = new Dictionary<string, object>{{
99+
"ConfigurationSection", "AzureAd2"
100+
}}
101+
}];
102+
});
103+
104+
IServiceProvider serviceProvider = tokenAcquirerFactory.Build();
105+
IAuthorizationHeaderProvider authorizationHeaderProvider =
106+
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
107+
44108
// Act
45-
_ = await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default");
46-
}
47-
catch (Exception ex) when (ex is not XunitException)
48-
{
49-
Assert.Fail(ex.Message);
109+
var result = await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(TestConstants.s_scopeForApp);
110+
111+
// Assert
112+
Assert.Equal("api://AzureADTokenExchange/.default", credentialRequestHttpHandler.ActualRequestPostData["scope"]);
113+
Assert.Equal(TestConstants.s_scopeForApp, tokenRequestHttpHandler.ActualRequestPostData["scope"]);
114+
Assert.Equal("c1", credentialRequestHttpHandler.ActualRequestPostData["client_id"]);
115+
Assert.Equal("https://login.microsoftonline.us/t1/oauth2/v2.0/token", credentialRequestHttpHandler.ActualRequestMessage?.RequestUri?.AbsoluteUri);
116+
Assert.Equal("c2", tokenRequestHttpHandler.ActualRequestPostData["client_id"]);
117+
Assert.Equal("https://login.microsoftonline.com/t2/oauth2/v2.0/token", tokenRequestHttpHandler.ActualRequestMessage?.RequestUri?.AbsoluteUri);
118+
119+
string? accessTokenFromRequest1;
120+
using (JsonDocument document = JsonDocument.Parse(credentialRequestHttpHandler.ResponseString))
121+
{
122+
accessTokenFromRequest1 = document.RootElement.GetProperty("access_token").GetString();
123+
}
124+
125+
// the jwt credential from request1 is used as credential on request2
126+
Assert.Equal(
127+
tokenRequestHttpHandler.ActualRequestPostData["client_assertion"],
128+
accessTokenFromRequest1);
50129
}
51-
}
130+
}
52131
}
53132
}

tests/E2E Tests/OidcIdPSignedAssertionProviderTests/OidcIdpSignedAssertionLoader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public async Task LoadIfNeededAsync(CredentialDescription credentialDescription,
5858
}
5959

6060
MicrosoftIdentityApplicationOptions microsoftIdentityApplicationOptions = _options.Get(sectionName);
61+
6162
if (string.IsNullOrEmpty(microsoftIdentityApplicationOptions.Instance) && microsoftIdentityApplicationOptions.Authority == "//v2.0")
6263
{
6364
_configuration.GetSection(sectionName).Bind(microsoftIdentityApplicationOptions);

tests/E2E Tests/OidcIdPSignedAssertionProviderTests/OidcIdpSignedAssertionProviderTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<ProjectReference Include="..\..\..\src\Microsoft.Identity.Web\Microsoft.Identity.Web.csproj" />
2929
<ProjectReference Include="..\..\..\src\Microsoft.Identity.Web.Certificate\Microsoft.Identity.Web.Certificate.csproj" />
3030
<ProjectReference Include="..\..\..\src\Microsoft.Identity.Web.Certificateless\Microsoft.Identity.Web.Certificateless.csproj" />
31+
<ProjectReference Include="..\..\Microsoft.Identity.Web.Test.Common\Microsoft.Identity.Web.Test.Common.csproj" />
3132
</ItemGroup>
3233

3334
<ItemGroup>

tests/E2E Tests/OidcIdPSignedAssertionProviderTests/appsettings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
2+
"$schema": "https://raw.githubusercontent.com/AzureAD/microsoft-identity-web/refs/heads/master/JsonSchemas/microsoft-identity-web.json",
23
"AzureAd": {
34
"Instance": "https://login.microsoftonline.com/",
45
"TenantId": "msidlab4.onmicrosoft.com",
6+
"ExtraQueryParameters": { "dc": "ESTS-PUB-WEULR1-AZ1-FD000-TEST1" },
57
"ClientId": "5e71875b-ae52-4a3c-8b82-f6fdc8e1dbe1", // this app is configured to trust credentials (tokens) from f6b698c0-140c-448f-8155-4aa9bf77ceba
68
"ClientCredentials": [
79
{
@@ -17,6 +19,8 @@
1719
"Instance": "https://login.microsoftonline.us/",
1820
"TenantId": "45ff0c17-f8b5-489b-b7fd-2fedebbec0c4",
1921
"ClientId": "f13080ee-01fe-48c1-8e9f-f0dd6f69ac7b",
22+
"ExtraQueryParameters": { "dc": "ESTS-PUB-WEULR1-AZ1-FD000-TEST1" },
23+
"SendX5C": true,
2024
"ClientCredentials": [
2125
{
2226
"SourceType": "StoreWithDistinguishedName",

tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpClientFactory.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88
using System.Net.Http.Headers;
99
using System.Runtime.InteropServices;
1010
using Microsoft.Identity.Client;
11+
using NSubstitute.Routing.Handlers;
1112
using Xunit;
1213

1314
namespace Microsoft.Identity.Web.Test.Common.Mocks
1415
{
1516
/// <summary>
1617
/// HttpClient that serves Http responses for testing purposes. Instance Discovery is added by default.
1718
/// </summary>
18-
public class MockHttpClientFactory : IMsalHttpClientFactory, IDisposable
19+
/// <remarks>
20+
/// This implements the both IHttpClientFactory, which is what ID.Web uses. And IMsalHttpClientFactory which is what MSAL uses.
21+
/// </remarks>
22+
public class MockHttpClientFactory : IMsalHttpClientFactory, IHttpClientFactory, IDisposable
1923
{
2024
/// <inheritdoc />
2125
public void Dispose()
@@ -58,5 +62,10 @@ public HttpClient GetHttpClient()
5862

5963
return httpClient;
6064
}
65+
66+
public HttpClient CreateClient(string name)
67+
{
68+
return GetHttpClient();
69+
}
6170
}
6271
}

tests/Microsoft.Identity.Web.Test.Common/Mocks/MockHttpMessageHandler.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public MockHttpMessageHandler()
3232

3333
public Exception ExceptionToThrow { get; set; }
3434

35+
public string ResponseString { get; private set; }
36+
3537
/// <summary>
3638
/// Once the http message is executed, this property holds the request message.
3739
/// </summary>
@@ -66,6 +68,8 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
6668
Content = new StringContent(TestConstants.DiscoveryJsonResponse),
6769
};
6870

71+
ResponseString = TestConstants.DiscoveryJsonResponse;
72+
6973
return responseMessage;
7074
}
7175

@@ -82,7 +86,9 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
8286

8387
Assert.Equal(ExpectedMethod, request.Method);
8488
await ValidatePostDataAsync(request);
85-
89+
90+
// Read the content of ResponseMessage.Content into a string variable
91+
ResponseString = await ResponseMessage.Content.ReadAsStringAsync();
8692

8793
return ResponseMessage;
8894
}

0 commit comments

Comments
 (0)