@@ -154,14 +154,15 @@ pub enum AuthError {
154154}
155155
156156/// oauth2 metadata
157- #[ derive( Debug , Clone , Deserialize , Serialize ) ]
157+ #[ derive( Debug , Clone , Deserialize , Serialize , Default ) ]
158158pub struct AuthorizationMetadata {
159159 pub authorization_endpoint : String ,
160160 pub token_endpoint : String ,
161161 pub registration_endpoint : Option < String > ,
162162 pub issuer : Option < String > ,
163163 pub jwks_uri : Option < String > ,
164164 pub scopes_supported : Option < Vec < String > > ,
165+ pub response_types_supported : Option < Vec < String > > ,
165166 // allow additional fields
166167 #[ serde( flatten) ]
167168 pub additional_fields : HashMap < String , serde_json:: Value > ,
@@ -379,7 +380,17 @@ impl AuthorizationManager {
379380 self . oauth_client = Some ( client_builder) ;
380381 Ok ( ( ) )
381382 }
382-
383+ /// validate if the server support the response type
384+ fn validate_response_supported ( & self , response_type : & str ) -> Result < ( ) , AuthError > {
385+ if let Some ( metadata) = self . metadata . as_ref ( ) {
386+ if let Some ( response_types_supported) = metadata. response_types_supported . as_ref ( ) {
387+ if !response_types_supported. contains ( & response_type. to_string ( ) ) {
388+ return Err ( AuthError :: InvalidScope ( response_type. to_string ( ) ) ) ;
389+ }
390+ }
391+ }
392+ Ok ( ( ) )
393+ }
383394 /// dynamic register oauth2 client
384395 pub async fn register_client (
385396 & mut self ,
@@ -397,6 +408,10 @@ impl AuthorizationManager {
397408 ) ) ;
398409 } ;
399410
411+ // RFC 8414 RECOMMENDS response_types_supported in the metadata. This field is optional,
412+ // but if present and does not include the flow we use ("code"), bail out early with a clear error.
413+ self . validate_response_supported ( "code" ) ?;
414+
400415 let registration_request = ClientRegistrationRequest {
401416 client_name : name. to_string ( ) ,
402417 redirect_uris : vec ! [ redirect_uri. to_string( ) ] ,
@@ -485,6 +500,9 @@ impl AuthorizationManager {
485500 . as_ref ( )
486501 . ok_or_else ( || AuthError :: InternalError ( "OAuth client not configured" . to_string ( ) ) ) ?;
487502
503+ // ensure the server supports the response type we intend to use when metadata is available
504+ self . validate_response_supported ( "code" ) ?;
505+
488506 // generate pkce challenge
489507 let ( pkce_challenge, pkce_verifier) = PkceCodeChallenge :: new_random_sha256 ( ) ;
490508
0 commit comments