@@ -98,14 +98,15 @@ pub enum AuthError {
9898}
9999
100100/// oauth2 metadata
101- #[ derive( Debug , Clone , Deserialize , Serialize ) ]
101+ #[ derive( Debug , Clone , Deserialize , Serialize , Default ) ]
102102pub struct AuthorizationMetadata {
103103 pub authorization_endpoint : String ,
104104 pub token_endpoint : String ,
105105 pub registration_endpoint : Option < String > ,
106106 pub issuer : Option < String > ,
107107 pub jwks_uri : Option < String > ,
108108 pub scopes_supported : Option < Vec < String > > ,
109+ pub response_types_supported : Option < Vec < String > > ,
109110 // allow additional fields
110111 #[ serde( flatten) ]
111112 pub additional_fields : HashMap < String , serde_json:: Value > ,
@@ -290,11 +291,7 @@ impl AuthorizationManager {
290291 Ok ( AuthorizationMetadata {
291292 authorization_endpoint : create_endpoint ( "authorize" ) ,
292293 token_endpoint : create_endpoint ( "token" ) ,
293- registration_endpoint : None ,
294- issuer : None ,
295- jwks_uri : None ,
296- scopes_supported : None ,
297- additional_fields : HashMap :: new ( ) ,
294+ ..Default :: default ( )
298295 } )
299296 }
300297
@@ -339,7 +336,17 @@ impl AuthorizationManager {
339336 self . oauth_client = Some ( client_builder) ;
340337 Ok ( ( ) )
341338 }
342-
339+ /// validate if the server support the response type
340+ fn validate_response_supported ( & self , response_type : & str ) -> Result < ( ) , AuthError > {
341+ if let Some ( metadata) = self . metadata . as_ref ( ) {
342+ if let Some ( response_types_supported) = metadata. response_types_supported . as_ref ( ) {
343+ if !response_types_supported. contains ( & response_type. to_string ( ) ) {
344+ return Err ( AuthError :: InvalidScope ( response_type. to_string ( ) ) ) ;
345+ }
346+ }
347+ }
348+ Ok ( ( ) )
349+ }
343350 /// dynamic register oauth2 client
344351 pub async fn register_client (
345352 & mut self ,
@@ -357,6 +364,10 @@ impl AuthorizationManager {
357364 ) ) ;
358365 } ;
359366
367+ // RFC 8414 RECOMMENDS response_types_supported in the metadata. This field is optional,
368+ // but if present and does not include the flow we use ("code"), bail out early with a clear error.
369+ self . validate_response_supported ( "code" ) ?;
370+
360371 // prepare registration request
361372 let registration_request = ClientRegistrationRequest {
362373 client_name : name. to_string ( ) ,
@@ -446,6 +457,9 @@ impl AuthorizationManager {
446457 . as_ref ( )
447458 . ok_or_else ( || AuthError :: InternalError ( "OAuth client not configured" . to_string ( ) ) ) ?;
448459
460+ // ensure the server supports the response type we intend to use when metadata is available
461+ self . validate_response_supported ( "code" ) ?;
462+
449463 // generate pkce challenge
450464 let ( pkce_challenge, pkce_verifier) = PkceCodeChallenge :: new_random_sha256 ( ) ;
451465
0 commit comments