Skip to content

Commit 9b5f382

Browse files
committed
fix(oauth): rfc8414 should judement the response_types
response_types_supported should be judement while try to do 'Authorization Code Flow' Signed-off-by: jokemanfire <[email protected]>
1 parent a211a71 commit 9b5f382

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

crates/rmcp/src/transport/auth.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
102102
pub 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

@@ -357,6 +354,16 @@ impl AuthorizationManager {
357354
));
358355
};
359356

357+
// RFC 8414 requires response_types_supported; if provided and doesn't include
358+
// the flow we use (code), bail out early with a clear error.
359+
if let Some(response_types_supported) = metadata.response_types_supported.as_ref() {
360+
if !response_types_supported.contains(&"code".to_string()) {
361+
return Err(AuthError::RegistrationFailed(
362+
"Server does not support response_type=code".to_string(),
363+
));
364+
}
365+
}
366+
360367
// prepare registration request
361368
let registration_request = ClientRegistrationRequest {
362369
client_name: name.to_string(),
@@ -446,6 +453,17 @@ impl AuthorizationManager {
446453
.as_ref()
447454
.ok_or_else(|| AuthError::InternalError("OAuth client not configured".to_string()))?;
448455

456+
// Ensure the server supports the response type we intend to use when metadata is available
457+
if let Some(metadata) = self.metadata.as_ref() {
458+
if let Some(response_types_supported) = metadata.response_types_supported.as_ref() {
459+
if !response_types_supported.contains(&"code".to_string()) {
460+
return Err(AuthError::RegistrationFailed(
461+
"Server does not support response_type=code".to_string(),
462+
));
463+
}
464+
}
465+
}
466+
449467
// generate pkce challenge
450468
let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();
451469

examples/servers/src/complex_auth_sse.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ async fn oauth_authorization_server() -> impl IntoResponse {
526526
token_endpoint: format!("http://{}/oauth/token", BIND_ADDRESS),
527527
scopes_supported: Some(vec!["profile".to_string(), "email".to_string()]),
528528
registration_endpoint: Some(format!("http://{}/oauth/register", BIND_ADDRESS)),
529+
response_types_supported: Some(vec!["code".to_string()]),
529530
issuer: Some(BIND_ADDRESS.to_string()),
530531
jwks_uri: Some(format!("http://{}/oauth/jwks", BIND_ADDRESS)),
531532
additional_fields,

0 commit comments

Comments
 (0)