22// Licensed under the MIT License.
33
44using System ;
5+ using System . Collections . Generic ;
6+ using System . IdentityModel . Tokens . Jwt ;
57using System . Linq ;
8+ using System . Net . Http ;
9+ using System . Text . Json ;
610using System . Threading . Tasks ;
11+ using Azure . Core ;
12+ using Microsoft . Extensions . Configuration ;
713using Microsoft . Extensions . DependencyInjection ;
814using Microsoft . Identity . Abstractions ;
915using Microsoft . Identity . Client ;
1016using Microsoft . Identity . Web ;
17+ using Microsoft . Identity . Web . Test . Common ;
18+ using Microsoft . Identity . Web . Test . Common . Mocks ;
1119using 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}
0 commit comments