Skip to content

Commit ce0ae93

Browse files
committed
chore: refactor OAuth client authorization api
`OAuthState::start_authorization` now accepts a declarative `AuthorizationRequest` describing the client's available identity material and selects the highest-priority mechanism the server supports: pre-registered client information → Client ID Metadata Documents (SEP-991) → Dynamic Client Registration. This replaces the three mechanism-specific entry points (`start_authorization`, `start_authorization_with_metadata_url`, `start_authorization_with_preregistered_client`), where callers previously had to know which mechanism to pick. `AuthorizationSession::new` is consolidated the same way, and the failure-recovery pattern from #994 (returning the manager alongside the error so `OAuthState` recovers to `Unauthorized` on transient failures) is now applied across all registration paths. Includes new `RecordingOAuthHttpClient`-based tests covering the priority matrix and recovery semantics, plus updated docs, examples, and conformance client.
1 parent 7d811c4 commit ce0ae93

5 files changed

Lines changed: 559 additions & 213 deletions

File tree

conformance/src/bin/client.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rmcp::{
44
service::RequestContext,
55
transport::{
66
AuthClient, AuthorizationManager, StreamableHttpClientTransport,
7-
auth::{AuthorizationCallback, OAuthState},
7+
auth::{AuthorizationCallback, AuthorizationRequest, OAuthState},
88
streamable_http_client::StreamableHttpClientTransportConfig,
99
},
1010
};
@@ -205,11 +205,10 @@ async fn perform_oauth_flow(
205205

206206
// Discover + register + get auth URL
207207
oauth
208-
.start_authorization_with_metadata_url(
209-
&[],
210-
REDIRECT_URI,
211-
Some("conformance-client"),
212-
Some(CIMD_CLIENT_METADATA_URL),
208+
.start_authorization(
209+
AuthorizationRequest::new(REDIRECT_URI)
210+
.with_client_name("conformance-client")
211+
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
213212
)
214213
.await?;
215214

@@ -254,10 +253,12 @@ async fn perform_oauth_flow_preregistered(
254253
) -> anyhow::Result<AuthClient<reqwest::Client>> {
255254
let mut oauth = OAuthState::new(server_url, None).await?;
256255

257-
let config = rmcp::transport::auth::OAuthClientConfig::new(client_id, REDIRECT_URI)
258-
.with_client_secret(client_secret);
259256
oauth
260-
.start_authorization_with_preregistered_client(config)
257+
.start_authorization(
258+
AuthorizationRequest::new(REDIRECT_URI)
259+
.with_preregistered_client(client_id)
260+
.with_client_secret(client_secret),
261+
)
261262
.await?;
262263

263264
let auth_url = oauth.get_authorization_url().await?;
@@ -313,11 +314,10 @@ async fn run_auth_scope_step_up_client(
313314
// First auth
314315
let mut oauth = OAuthState::new(server_url, None).await?;
315316
oauth
316-
.start_authorization_with_metadata_url(
317-
&[],
318-
REDIRECT_URI,
319-
Some("conformance-client"),
320-
Some(CIMD_CLIENT_METADATA_URL),
317+
.start_authorization(
318+
AuthorizationRequest::new(REDIRECT_URI)
319+
.with_client_name("conformance-client")
320+
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
321321
)
322322
.await?;
323323

@@ -363,11 +363,11 @@ async fn run_auth_scope_step_up_client(
363363

364364
let mut oauth2 = OAuthState::new(server_url, None).await?;
365365
oauth2
366-
.start_authorization_with_metadata_url(
367-
SCOPE_STEP_UP_ESCALATED_SCOPES,
368-
REDIRECT_URI,
369-
Some("conformance-client"),
370-
Some(CIMD_CLIENT_METADATA_URL),
366+
.start_authorization(
367+
AuthorizationRequest::new(REDIRECT_URI)
368+
.with_scopes(SCOPE_STEP_UP_ESCALATED_SCOPES.iter().copied())
369+
.with_client_name("conformance-client")
370+
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
371371
)
372372
.await?;
373373
let auth_url2 = oauth2.get_authorization_url().await?;
@@ -413,11 +413,10 @@ async fn run_auth_scope_retry_limit_client(
413413
loop {
414414
let mut oauth = OAuthState::new(server_url, None).await?;
415415
oauth
416-
.start_authorization_with_metadata_url(
417-
&[],
418-
REDIRECT_URI,
419-
Some("conformance-client"),
420-
Some(CIMD_CLIENT_METADATA_URL),
416+
.start_authorization(
417+
AuthorizationRequest::new(REDIRECT_URI)
418+
.with_client_name("conformance-client")
419+
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
421420
)
422421
.await?;
423422
let auth_url = oauth.get_authorization_url().await?;

crates/rmcp/src/transport.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ pub mod auth;
9999
pub use auth::JwtSigningAlgorithm;
100100
#[cfg(feature = "auth")]
101101
pub use auth::{
102-
AuthClient, AuthError, AuthorizationManager, AuthorizationSession, AuthorizedHttpClient,
103-
ClientCredentialsConfig, CredentialStore, EXTENSION_OAUTH_CLIENT_CREDENTIALS,
104-
InMemoryCredentialStore, InMemoryStateStore, OAuthHttpClient, OAuthHttpClientError,
105-
OAuthHttpClientFuture, OAuthHttpRedirectPolicy, OAuthHttpRequest, ScopeUpgradeConfig,
106-
StateStore, StoredAuthorizationState, StoredCredentials, WWWAuthenticateParams,
102+
AuthClient, AuthError, AuthorizationManager, AuthorizationRequest, AuthorizationSession,
103+
AuthorizedHttpClient, ClientCredentialsConfig, CredentialStore,
104+
EXTENSION_OAUTH_CLIENT_CREDENTIALS, InMemoryCredentialStore, InMemoryStateStore,
105+
OAuthHttpClient, OAuthHttpClientError, OAuthHttpClientFuture, OAuthHttpRedirectPolicy,
106+
OAuthHttpRequest, ScopeUpgradeConfig, StateStore, StoredAuthorizationState, StoredCredentials,
107+
WWWAuthenticateParams,
107108
};
108109

109110
// #[cfg(feature = "transport-ws")]

0 commit comments

Comments
 (0)