@@ -1248,56 +1248,56 @@ impl AuthorizationManager {
12481248 /// the client if credentials are found. Returns `false` when credentials
12491249 /// are absent or discarded after an authorization-server change.
12501250 pub async fn initialize_from_store ( & mut self ) -> Result < bool , AuthError > {
1251- if let Some ( stored) = self . credential_store . load ( ) . await ? {
1252- if stored. token_response . is_some ( ) {
1253- if self . metadata . is_none ( ) {
1254- let metadata = self . discover_metadata ( ) . await ?;
1255- self . metadata = Some ( metadata) ;
1256- }
1257-
1258- if let ( Some ( stored_issuer) , Some ( current_issuer) ) =
1259- ( stored. issuer . as_deref ( ) , self . metadata_issuer ( ) . as_deref ( ) )
1260- {
1261- // A CIMD client ID is the client's metadata URL, so it is
1262- // portable across authorization servers and exempt here.
1263- if stored_issuer != current_issuer {
1264- if is_https_url ( & stored. client_id ) {
1265- // A CIMD client ID is the client's metadata URL, so it is
1266- // portable across authorization servers — but the tokens
1267- // were minted by the previous AS and must not be reused.
1268- tracing:: warn!(
1269- stored_issuer,
1270- current_issuer,
1271- "authorization server issuer changed; discarding tokens but keeping portable CIMD client ID"
1272- ) ;
1273- self . credential_store
1274- . save (
1275- StoredCredentials :: new (
1276- stored. client_id . clone ( ) ,
1277- None ,
1278- vec ! [ ] ,
1279- None ,
1280- )
1281- . with_issuer ( self . metadata_issuer ( ) ) ,
1282- )
1283- . await ?;
1284- self . configure_client_id ( & stored. client_id ) ?;
1285- return Ok ( false ) ;
1286- }
1251+ if let Some ( stored) = self . credential_store . load ( ) . await ?
1252+ && stored. token_response . is_some ( )
1253+ {
1254+ if self . metadata . is_none ( ) {
1255+ let metadata = self . discover_metadata ( ) . await ?;
1256+ self . metadata = Some ( metadata) ;
1257+ }
12871258
1259+ if let ( Some ( stored_issuer) , Some ( current_issuer) ) =
1260+ ( stored. issuer . as_deref ( ) , self . metadata_issuer ( ) . as_deref ( ) )
1261+ {
1262+ // A CIMD client ID is the client's metadata URL, so it is
1263+ // portable across authorization servers and exempt here.
1264+ if stored_issuer != current_issuer {
1265+ if is_https_url ( & stored. client_id ) {
1266+ // A CIMD client ID is the client's metadata URL, so it is
1267+ // portable across authorization servers — but the tokens
1268+ // were minted by the previous AS and must not be reused.
12881269 tracing:: warn!(
12891270 stored_issuer,
12901271 current_issuer,
1291- "authorization server issuer changed; clearing stored credentials bound to the previous issuer "
1272+ "authorization server issuer changed; discarding tokens but keeping portable CIMD client ID "
12921273 ) ;
1293- self . credential_store . clear ( ) . await ?;
1274+ self . credential_store
1275+ . save (
1276+ StoredCredentials :: new (
1277+ stored. client_id . clone ( ) ,
1278+ None ,
1279+ vec ! [ ] ,
1280+ None ,
1281+ )
1282+ . with_issuer ( self . metadata_issuer ( ) ) ,
1283+ )
1284+ . await ?;
1285+ self . configure_client_id ( & stored. client_id ) ?;
12941286 return Ok ( false ) ;
12951287 }
1296- }
12971288
1298- self . configure_client_id ( & stored. client_id ) ?;
1299- return Ok ( true ) ;
1289+ tracing:: warn!(
1290+ stored_issuer,
1291+ current_issuer,
1292+ "authorization server issuer changed; clearing stored credentials bound to the previous issuer"
1293+ ) ;
1294+ self . credential_store . clear ( ) . await ?;
1295+ return Ok ( false ) ;
1296+ }
13001297 }
1298+
1299+ self . configure_client_id ( & stored. client_id ) ?;
1300+ return Ok ( true ) ;
13011301 }
13021302 Ok ( false )
13031303 }
@@ -1425,10 +1425,10 @@ impl AuthorizationManager {
14251425
14261426 // RFC 8414 RECOMMENDS response_types_supported in the metadata. This field is optional,
14271427 // but if present and does not include the flow we use ("code"), bail out early with a clear error.
1428- if let Some ( response_types_supported) = metadata. response_types_supported . as_ref ( ) {
1429- if !response_types_supported. contains ( & response_type. to_string ( ) ) {
1430- return Err ( AuthError :: InvalidScope ( response_type . to_string ( ) ) ) ;
1431- }
1428+ if let Some ( response_types_supported) = metadata. response_types_supported . as_ref ( )
1429+ && !response_types_supported. contains ( & response_type. to_string ( ) )
1430+ {
1431+ return Err ( AuthError :: InvalidScope ( response_type . to_string ( ) ) ) ;
14321432 }
14331433
14341434 // The client always sends an S256 challenge. A server that advertises
@@ -1713,12 +1713,11 @@ impl AuthorizationManager {
17131713 }
17141714
17151715 // nothing requested or challenged yet: seed from AS metadata, then caller defaults
1716- if let Some ( metadata) = & self . metadata {
1717- if let Some ( scopes_supported) = & metadata. scopes_supported {
1718- if !scopes_supported. is_empty ( ) {
1719- return scopes_supported. clone ( ) ;
1720- }
1721- }
1716+ if let Some ( metadata) = & self . metadata
1717+ && let Some ( scopes_supported) = & metadata. scopes_supported
1718+ && !scopes_supported. is_empty ( )
1719+ {
1720+ return scopes_supported. clone ( ) ;
17221721 }
17231722
17241723 default_scopes. iter ( ) . map ( |s| s. to_string ( ) ) . collect ( )
@@ -1730,12 +1729,11 @@ impl AuthorizationManager {
17301729 if scopes. is_empty ( ) || scopes. iter ( ) . any ( |s| s == "offline_access" ) {
17311730 return ;
17321731 }
1733- if let Some ( metadata) = & self . metadata {
1734- if let Some ( supported) = & metadata. scopes_supported {
1735- if supported. iter ( ) . any ( |s| s == "offline_access" ) {
1736- scopes. push ( "offline_access" . to_string ( ) ) ;
1737- }
1738- }
1732+ if let Some ( metadata) = & self . metadata
1733+ && let Some ( supported) = & metadata. scopes_supported
1734+ && supported. iter ( ) . any ( |s| s == "offline_access" )
1735+ {
1736+ scopes. push ( "offline_access" . to_string ( ) ) ;
17391737 }
17401738 }
17411739
@@ -2255,10 +2253,10 @@ impl AuthorizationManager {
22552253 self . validate_resource_metadata_resource ( & resource_metadata) ?;
22562254
22572255 // store scopes_supported from protected resource metadata for select_scopes()
2258- if let Some ( scopes) = resource_metadata. scopes_supported {
2259- if !scopes. is_empty ( ) {
2260- * self . resource_scopes . write ( ) . await = scopes ;
2261- }
2256+ if let Some ( scopes) = resource_metadata. scopes_supported
2257+ && !scopes. is_empty ( )
2258+ {
2259+ * self . resource_scopes . write ( ) . await = scopes ;
22622260 }
22632261
22642262 let mut candidates = Vec :: new ( ) ;
@@ -2701,20 +2699,18 @@ impl AuthorizationManager {
27012699 if let ClientCredentialsConfig :: PrivateKeyJwt {
27022700 signing_algorithm, ..
27032701 } = config
2704- {
2705- if let Some ( algs) = metadata
2702+ && let Some ( algs) = metadata
27062703 . additional_fields
27072704 . get ( "token_endpoint_auth_signing_alg_values_supported" )
27082705 . and_then ( |v| v. as_array ( ) )
2709- {
2710- let alg_str = signing_algorithm. as_str ( ) ;
2711- if !algs. iter ( ) . any ( |a| a. as_str ( ) == Some ( alg_str) ) {
2712- let supported: Vec < & str > = algs. iter ( ) . filter_map ( |a| a. as_str ( ) ) . collect ( ) ;
2713- return Err ( AuthError :: ClientCredentialsError ( format ! (
2714- "Authorization server does not support signing algorithm '{}'. Supported: {:?}" ,
2715- alg_str, supported
2716- ) ) ) ;
2717- }
2706+ {
2707+ let alg_str = signing_algorithm. as_str ( ) ;
2708+ if !algs. iter ( ) . any ( |a| a. as_str ( ) == Some ( alg_str) ) {
2709+ let supported: Vec < & str > = algs. iter ( ) . filter_map ( |a| a. as_str ( ) ) . collect ( ) ;
2710+ return Err ( AuthError :: ClientCredentialsError ( format ! (
2711+ "Authorization server does not support signing algorithm '{}'. Supported: {:?}" ,
2712+ alg_str, supported
2713+ ) ) ) ;
27182714 }
27192715 }
27202716
0 commit comments