@@ -668,5 +668,73 @@ private static HttpResponseMessage CreateResponse(
668
668
{
669
669
return MockHelpers . CreateSuccessfulClientCredentialTokenResponseMessage ( token , expiresIn , tokenType ) ;
670
670
}
671
+
672
+ [ TestMethod ]
673
+ public async Task AcquireTokenForClient_WithMtlsPop_Dsts_SuccessAsync ( )
674
+ {
675
+ string authorityUrl = TestConstants . DstsAuthorityTenanted ;
676
+
677
+ // Modify the endpoint based on the authorityUrl
678
+ string expectedTokenEndpoint = $ "{ authorityUrl } oauth2/v2.0/token";
679
+
680
+ using ( var httpManager = new MockHttpManager ( ) )
681
+ {
682
+ // Set up mock handler with expected token endpoint URL
683
+ httpManager . AddMockHandler ( new MockHttpMessageHandler ( )
684
+ {
685
+ ExpectedUrl = expectedTokenEndpoint ,
686
+ ExpectedMethod = HttpMethod . Post ,
687
+ ResponseMessage = MockHelpers . CreateSuccessfulClientCredentialTokenResponseMessage ( tokenType : "mtls_pop" )
688
+ } ) ;
689
+
690
+ var app = ConfidentialClientApplicationBuilder . Create ( TestConstants . ClientId )
691
+ . WithCertificate ( s_testCertificate )
692
+ . WithAuthority ( authorityUrl )
693
+ . WithExperimentalFeatures ( )
694
+ . WithHttpManager ( httpManager )
695
+ . BuildConcrete ( ) ;
696
+
697
+ // First token acquisition - should hit the identity provider
698
+ AuthenticationResult result = await app . AcquireTokenForClient ( TestConstants . s_scope )
699
+ . WithMtlsProofOfPossession ( )
700
+ . ExecuteAsync ( )
701
+ . ConfigureAwait ( false ) ;
702
+
703
+ Assert . AreEqual ( "header.payload.signature" , result . AccessToken ) ;
704
+ Assert . AreEqual ( Constants . MtlsPoPAuthHeaderPrefix , result . TokenType ) ;
705
+ Assert . AreEqual ( null , result . AuthenticationResultMetadata . RegionDetails . RegionUsed ) ;
706
+ Assert . AreEqual ( expectedTokenEndpoint , result . AuthenticationResultMetadata . TokenEndpoint ) ;
707
+
708
+ // Second token acquisition - should retrieve from cache
709
+ AuthenticationResult secondResult = await app . AcquireTokenForClient ( TestConstants . s_scope )
710
+ . WithMtlsProofOfPossession ( )
711
+ . ExecuteAsync ( )
712
+ . ConfigureAwait ( false ) ;
713
+
714
+ Assert . AreEqual ( "header.payload.signature" , secondResult . AccessToken ) ;
715
+ Assert . AreEqual ( Constants . MtlsPoPAuthHeaderPrefix , secondResult . TokenType ) ;
716
+ Assert . AreEqual ( TokenSource . Cache , secondResult . AuthenticationResultMetadata . TokenSource ) ;
717
+ }
718
+ }
719
+
720
+ [ TestMethod ]
721
+ public async Task MtlsPopDstsCommonAuthorityFailsAsync ( )
722
+ {
723
+ IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
724
+ . Create ( TestConstants . ClientId )
725
+ . WithAuthority ( TestConstants . DstsAuthorityCommon )
726
+ . WithCertificate ( s_testCertificate )
727
+ . WithExperimentalFeatures ( )
728
+ . Build ( ) ;
729
+
730
+ // Set WithMtlsProofOfPossession on the request without specifying an authority
731
+ MsalClientException ex = await AssertException . TaskThrowsAsync < MsalClientException > ( ( ) =>
732
+ app . AcquireTokenForClient ( TestConstants . s_scope )
733
+ . WithMtlsProofOfPossession ( )
734
+ . ExecuteAsync ( ) )
735
+ . ConfigureAwait ( false ) ;
736
+
737
+ Assert . AreEqual ( MsalError . MissingTenantedAuthority , ex . ErrorCode ) ;
738
+ }
671
739
}
672
740
}
0 commit comments