1616using System . Threading . Tasks ;
1717using IdentityModel . Client ;
1818using Xunit ;
19+ using System . Web ;
1920
2021namespace IdentityModel . OidcClient . Tests
2122{
@@ -486,5 +487,82 @@ public async Task Malformed_identity_token_on_token_response_should_fail()
486487 result . IsError . Should ( ) . BeTrue ( ) ;
487488 result . Error . Should ( ) . Contain ( "invalid_jwt" ) ;
488489 }
490+
491+ [ Fact ]
492+ public async Task Authorize_should_push_parameters_when_PAR_is_enabled ( )
493+ {
494+ // Configure the client for PAR, authenticating with a client secret
495+ _options . ClientSecret = "secret" ;
496+ _options . ProviderInformation . PushedAuthorizationRequestEndpoint = "https://this-is-set-so-par-will-be-used" ;
497+ var client = new OidcClient ( _options ) ;
498+
499+ // Mock the response from the par endpoint
500+ var requestUri = "mocked_request_uri" ;
501+ var parResponse = new Dictionary < string , string >
502+ {
503+ { "request_uri" , requestUri }
504+ } ;
505+ var backChannelHandler = new NetworkHandler ( JsonSerializer . Serialize ( parResponse ) , HttpStatusCode . OK ) ;
506+ _options . BackchannelHandler = backChannelHandler ;
507+
508+ // Prepare the login to cause the backchannel PAR request
509+ var state = await client . PrepareLoginAsync ( ) ;
510+
511+ // Validate that the resulting PAR state is correct
512+ var startUrl = new Uri ( state . StartUrl ) ;
513+ var startUrlQueryParams = HttpUtility . ParseQueryString ( startUrl . Query ) ;
514+ startUrlQueryParams . Should ( ) . HaveCount ( 2 ) ;
515+ startUrlQueryParams . GetValues ( "client_id" ) . Single ( ) . Should ( ) . Be ( "client" ) ;
516+ startUrlQueryParams . GetValues ( "request_uri" ) . Single ( ) . Should ( ) . Be ( requestUri ) ;
517+
518+ // Validate that the client authentication during the PAR request was correct
519+ var request = backChannelHandler . Request ;
520+ request . Headers . Authorization . Should ( ) . NotBeNull ( ) ;
521+ request . Headers . Authorization . Scheme . Should ( ) . Be ( "Basic" ) ;
522+ request . Headers . Authorization . Parameter . Should ( )
523+ . Be ( BasicAuthenticationOAuthHeaderValue . EncodeCredential ( "client" , "secret" ) ) ;
524+ }
525+
526+ [ Fact ]
527+ public async Task Par_request_should_include_client_assertion_in_body ( )
528+ {
529+ // Configure the client for PAR, authenticating with a client assertion
530+ var clientAssertion = "mocked_client_assertion" ;
531+ var clientAssertionType = "mocked_assertion_type" ;
532+ _options . ClientAssertion = new ClientAssertion
533+ {
534+ Type = clientAssertionType ,
535+ Value = clientAssertion
536+ } ;
537+ _options . ProviderInformation . PushedAuthorizationRequestEndpoint = "https://this-is-set-so-par-will-be-used" ;
538+ var client = new OidcClient ( _options ) ;
539+
540+ // Mock the response from the par endpoint
541+ var requestUri = "mocked_request_uri" ;
542+ var parResponse = new Dictionary < string , string >
543+ {
544+ { "request_uri" , requestUri }
545+ } ;
546+ var backChannelHandler = new NetworkHandler ( JsonSerializer . Serialize ( parResponse ) , HttpStatusCode . OK ) ;
547+ _options . BackchannelHandler = backChannelHandler ;
548+
549+ // Prepare the login to cause the backchannel PAR request
550+ var state = await client . PrepareLoginAsync ( ) ;
551+
552+ // Validate that the resulting PAR state is correct
553+ var startUrl = new Uri ( state . StartUrl ) ;
554+ var startUrlQueryParams = HttpUtility . ParseQueryString ( startUrl . Query ) ;
555+ startUrlQueryParams . Should ( ) . HaveCount ( 2 ) ;
556+ startUrlQueryParams . GetValues ( "client_id" ) . Single ( ) . Should ( ) . Be ( "client" ) ;
557+ startUrlQueryParams . GetValues ( "request_uri" ) . Single ( ) . Should ( ) . Be ( requestUri ) ;
558+
559+ // Validate that the client authentication during the PAR request was correct
560+ var parRequest = backChannelHandler . Request ;
561+ var parContent = await parRequest . Content . ReadAsStringAsync ( ) ;
562+ var parParams = HttpUtility . ParseQueryString ( parContent ) ;
563+ parParams . GetValues ( "client_assertion" ) . Single ( ) . Should ( ) . Be ( clientAssertion ) ;
564+ parParams . GetValues ( "client_assertion_type" ) . Single ( ) . Should ( ) . Be ( clientAssertionType ) ;
565+ parRequest . Headers . Authorization . Should ( ) . BeNull ( ) ;
566+ }
489567 }
490568}
0 commit comments