chore: refactor OAuth client authorization api (#1009)
* refactor!: 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. * fix: dcr registration uses requested application type * fix: error for invalid combination
This commit is contained in:
parent
5554a41d67
commit
e903341136
1 changed files with 625 additions and 219 deletions
|
|
@ -4,7 +4,7 @@ use rmcp::{
|
|||
service::RequestContext,
|
||||
transport::{
|
||||
AuthClient, AuthorizationManager, StreamableHttpClientTransport,
|
||||
auth::{AuthorizationCallback, InMemoryCredentialStore, OAuthState},
|
||||
auth::{AuthorizationCallback, AuthorizationRequest, InMemoryCredentialStore, OAuthState},
|
||||
streamable_http_client::StreamableHttpClientTransportConfig,
|
||||
},
|
||||
};
|
||||
|
|
@ -206,11 +206,10 @@ async fn perform_oauth_flow(
|
|||
|
||||
// Discover + register + get auth URL
|
||||
oauth
|
||||
.start_authorization_with_metadata_url(
|
||||
&[],
|
||||
REDIRECT_URI,
|
||||
Some("conformance-client"),
|
||||
Some(CIMD_CLIENT_METADATA_URL),
|
||||
.start_authorization(
|
||||
AuthorizationRequest::new(REDIRECT_URI)
|
||||
.with_client_name("conformance-client")
|
||||
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
@ -255,10 +254,12 @@ async fn perform_oauth_flow_preregistered(
|
|||
) -> anyhow::Result<AuthClient<reqwest::Client>> {
|
||||
let mut oauth = OAuthState::new(server_url, None).await?;
|
||||
|
||||
let config = rmcp::transport::auth::OAuthClientConfig::new(client_id, REDIRECT_URI)
|
||||
.with_client_secret(client_secret);
|
||||
oauth
|
||||
.start_authorization_with_preregistered_client(config)
|
||||
.start_authorization(
|
||||
AuthorizationRequest::new(REDIRECT_URI)
|
||||
.with_preregistered_client(client_id)
|
||||
.with_client_secret(client_secret),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let auth_url = oauth.get_authorization_url().await?;
|
||||
|
|
@ -323,11 +324,11 @@ async fn run_auth_scope_step_up_client(
|
|||
) -> anyhow::Result<()> {
|
||||
let mut oauth = OAuthState::new(server_url, None).await?;
|
||||
oauth
|
||||
.start_authorization_with_metadata_url(
|
||||
SCOPE_STEP_UP_INITIAL_SCOPES,
|
||||
REDIRECT_URI,
|
||||
Some("conformance-client"),
|
||||
Some(CIMD_CLIENT_METADATA_URL),
|
||||
.start_authorization(
|
||||
AuthorizationRequest::new(REDIRECT_URI)
|
||||
.with_scopes(SCOPE_STEP_UP_INITIAL_SCOPES.iter().copied())
|
||||
.with_client_name("conformance-client")
|
||||
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
@ -375,11 +376,11 @@ async fn run_auth_scope_step_up_client(
|
|||
|
||||
let mut oauth2 = OAuthState::new(server_url, None).await?;
|
||||
oauth2
|
||||
.start_authorization_with_metadata_url(
|
||||
SCOPE_STEP_UP_ESCALATED_SCOPES,
|
||||
REDIRECT_URI,
|
||||
Some("conformance-client"),
|
||||
Some(CIMD_CLIENT_METADATA_URL),
|
||||
.start_authorization(
|
||||
AuthorizationRequest::new(REDIRECT_URI)
|
||||
.with_scopes(SCOPE_STEP_UP_ESCALATED_SCOPES.iter().copied())
|
||||
.with_client_name("conformance-client")
|
||||
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
|
||||
)
|
||||
.await?;
|
||||
let auth_url2 = oauth2.get_authorization_url().await?;
|
||||
|
|
@ -427,11 +428,10 @@ async fn run_auth_scope_retry_limit_client(
|
|||
loop {
|
||||
let mut oauth = OAuthState::new(server_url, None).await?;
|
||||
oauth
|
||||
.start_authorization_with_metadata_url(
|
||||
&[],
|
||||
REDIRECT_URI,
|
||||
Some("conformance-client"),
|
||||
Some(CIMD_CLIENT_METADATA_URL),
|
||||
.start_authorization(
|
||||
AuthorizationRequest::new(REDIRECT_URI)
|
||||
.with_client_name("conformance-client")
|
||||
.with_client_metadata_url(CIMD_CLIENT_METADATA_URL),
|
||||
)
|
||||
.await?;
|
||||
let auth_url = oauth.get_authorization_url().await?;
|
||||
|
|
|
|||
Loading…
Reference in a new issue