fix: re-register after auth server change (#1011)

This commit is contained in:
Dale Seo 2026-07-21 12:14:30 -04:00 • committed by GitHub
commit 4e36fd9531
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 34 additions and 11 deletions

View file

@ -23,6 +23,3 @@ client:
# Auth feature gaps in the 2026-07-28 auth scenarios.
# tracked in #1002
- auth/scope-step-up
# SEP-2352: SDK lacks issuer-stamped credential storage (#879), so the
# sep-2352-reregister-on-as-change check fails.
- auth/authorization-server-migration

View file

@ -1088,7 +1088,8 @@ impl AuthorizationManager {
/// Initialize from stored credentials if available
///
/// This will load credentials from the credential store and configure
/// the client if credentials are found.
/// the client if credentials are found. Returns `false` when credentials
/// are absent or discarded after an authorization-server change.
pub async fn initialize_from_store(&mut self) -> Result<bool, AuthError> {
if let Some(stored) = self.credential_store.load().await? {
if stored.token_response.is_some() {
@ -1133,10 +1134,7 @@ impl AuthorizationManager {
"authorization server issuer changed; clearing stored credentials bound to the previous issuer"
);
self.credential_store.clear().await?;
return Err(AuthError::AuthorizationServerMismatch {
expected_issuer: stored_issuer.to_string(),
received_issuer: current_issuer.to_string(),
});
return Ok(false);
}
}
@ -3549,9 +3547,9 @@ mod tests {
use super::{
AuthError, AuthorizationCallback, AuthorizationManager, AuthorizationMetadata,
InMemoryStateStore, OAuthClientConfig, OAuthHttpClient, OAuthHttpClientError,
OAuthHttpClientFuture, OAuthHttpRedirectPolicy, OAuthHttpRequest, ScopeUpgradeConfig,
StateStore, StoredAuthorizationState, is_https_url,
CredentialStore, InMemoryCredentialStore, InMemoryStateStore, OAuthClientConfig,
OAuthHttpClient, OAuthHttpClientError, OAuthHttpClientFuture, OAuthHttpRedirectPolicy,
OAuthHttpRequest, ScopeUpgradeConfig, StateStore, StoredAuthorizationState, is_https_url,
};
use crate::transport::auth::VendorExtraTokenFields;
@ -5134,6 +5132,34 @@ mod tests {
mgr
}
#[tokio::test]
async fn initialize_from_store_clears_dcr_credentials_when_issuer_changes() {
let store = InMemoryCredentialStore::new();
store
.save(StoredCredentials {
client_id: "dcr-client".to_string(),
token_response: Some(make_token_response("old-token", Some(3600))),
granted_scopes: vec![],
token_received_at: Some(AuthorizationManager::now_epoch_secs()),
issuer: Some("https://old.example.com".to_string()),
})
.await
.unwrap();
let mut manager = manager_with_metadata(Some(AuthorizationMetadata {
authorization_endpoint: "https://new.example.com/authorize".to_string(),
token_endpoint: "https://new.example.com/token".to_string(),
issuer: Some("https://new.example.com".to_string()),
..Default::default()
}))
.await;
manager.set_credential_store(store.clone());
let initialized = manager.initialize_from_store().await.unwrap();
let credentials_cleared = store.load().await.unwrap().is_none();
assert_eq!((initialized, credentials_cleared), (false, true));
}
fn test_client_config() -> OAuthClientConfig {
OAuthClientConfig {
client_id: "my-client".to_string(),