Skip to content

Commit 0db2c0a

Browse files
committed
fix(oauth): The dynamic client registration should be optional
Signed-off-by: jokemanfire <[email protected]>
1 parent 0566d13 commit 0db2c0a

File tree

2 files changed

+16
-19
lines changed

2 files changed

+16
-19
lines changed

crates/rmcp/src/transport/auth.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use reqwest::{Client as HttpClient, IntoUrl, StatusCode, Url, header::AUTHORIZAT
1414
use serde::{Deserialize, Serialize};
1515
use thiserror::Error;
1616
use tokio::sync::{Mutex, RwLock};
17-
use tracing::{debug, error};
17+
use tracing::{debug, error, warn};
1818

1919
const DEFAULT_EXCHANGE_URL: &str = "http://localhost";
2020

@@ -102,7 +102,7 @@ pub enum AuthError {
102102
pub struct AuthorizationMetadata {
103103
pub authorization_endpoint: String,
104104
pub token_endpoint: String,
105-
pub registration_endpoint: String,
105+
pub registration_endpoint: Option<String>,
106106
pub issuer: Option<String>,
107107
pub jwks_uri: Option<String>,
108108
pub scopes_supported: Option<Vec<String>>,
@@ -273,7 +273,7 @@ impl AuthorizationManager {
273273
return Ok(metadata);
274274
}
275275

276-
debug!("No valid .well-known endpoint found, falling back to default endpoints");
276+
warn!("No valid .well-known endpoint found, falling back to default endpoints");
277277

278278
// fallback to default endpoints
279279
let mut auth_base = self.base_url.clone();
@@ -290,7 +290,7 @@ impl AuthorizationManager {
290290
Ok(AuthorizationMetadata {
291291
authorization_endpoint: create_endpoint("authorize"),
292292
token_endpoint: create_endpoint("token"),
293-
registration_endpoint: create_endpoint("register"),
293+
registration_endpoint: None,
294294
issuer: None,
295295
jwks_uri: None,
296296
scopes_supported: None,
@@ -323,12 +323,10 @@ impl AuthorizationManager {
323323
let token_url = TokenUrl::new(metadata.token_endpoint.clone())
324324
.map_err(|e| AuthError::OAuthError(format!("Invalid token URL: {}", e)))?;
325325

326-
// debug!("token url: {:?}", token_url);
327326
let client_id = ClientId::new(config.client_id);
328327
let redirect_url = RedirectUrl::new(config.redirect_uri.clone())
329328
.map_err(|e| AuthError::OAuthError(format!("Invalid re URL: {}", e)))?;
330329

331-
debug!("client_id: {:?}", client_id);
332330
let mut client_builder = BasicClient::new(client_id.clone())
333331
.set_auth_uri(auth_url)
334332
.set_token_uri(token_url)
@@ -349,14 +347,16 @@ impl AuthorizationManager {
349347
redirect_uri: &str,
350348
) -> Result<OAuthClientConfig, AuthError> {
351349
if self.metadata.is_none() {
352-
error!("No authorization support detected");
353350
return Err(AuthError::NoAuthorizationSupport);
354351
}
355352

356353
let metadata = self.metadata.as_ref().unwrap();
357-
let registration_url = metadata.registration_endpoint.clone();
354+
let Some(registration_url) = metadata.registration_endpoint.as_ref() else {
355+
return Err(AuthError::RegistrationFailed(
356+
"Dynamic client registration not supported".to_string(),
357+
));
358+
};
358359

359-
debug!("registration url: {:?}", registration_url);
360360
// prepare registration request
361361
let registration_request = ClientRegistrationRequest {
362362
client_name: name.to_string(),
@@ -369,8 +369,6 @@ impl AuthorizationManager {
369369
response_types: vec!["code".to_string()],
370370
};
371371

372-
debug!("registration request: {:?}", registration_request);
373-
374372
let response = match self
375373
.http_client
376374
.post(registration_url)
@@ -380,7 +378,6 @@ impl AuthorizationManager {
380378
{
381379
Ok(response) => response,
382380
Err(e) => {
383-
error!("Registration request failed: {}", e);
384381
return Err(AuthError::RegistrationFailed(format!(
385382
"HTTP request error: {}",
386383
e
@@ -395,7 +392,6 @@ impl AuthorizationManager {
395392
Err(_) => "cannot get error details".to_string(),
396393
};
397394

398-
error!("Registration failed: HTTP {} - {}", status, error_text);
399395
return Err(AuthError::RegistrationFailed(format!(
400396
"HTTP {}: {}",
401397
status, error_text
@@ -406,7 +402,6 @@ impl AuthorizationManager {
406402
let reg_response = match response.json::<ClientRegistrationResponse>().await {
407403
Ok(response) => response,
408404
Err(e) => {
409-
error!("Failed to parse registration response: {}", e);
410405
return Err(AuthError::RegistrationFailed(format!(
411406
"analyze response error: {}",
412407
e
@@ -471,7 +466,6 @@ impl AuthorizationManager {
471466
pkce_verifier,
472467
csrf_token,
473468
});
474-
debug!("set authorization state: {:?}", self.state.read().await);
475469

476470
Ok(auth_url.to_string())
477471
}
@@ -624,9 +618,9 @@ impl AuthorizationSession {
624618
scopes: &[&str],
625619
redirect_uri: &str,
626620
) -> Result<Self, AuthError> {
627-
// set redirect uri
621+
// Defualt client config
628622
let config = OAuthClientConfig {
629-
client_id: "mcp-client".to_string(), // temporary id, will be updated by dynamic registration
623+
client_id: "mcp-client".to_string(),
630624
client_secret: None,
631625
scopes: scopes.iter().map(|s| s.to_string()).collect(),
632626
redirect_uri: redirect_uri.to_string(),
@@ -639,7 +633,10 @@ impl AuthorizationSession {
639633
{
640634
Ok(config) => config,
641635
Err(e) => {
642-
eprintln!("Dynamic registration failed: {}", e);
636+
warn!(
637+
"Dynamic registration failed: {}, fallback to default config",
638+
e
639+
);
643640
// fallback to default config
644641
config
645642
}

examples/servers/src/complex_auth_sse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ async fn oauth_authorization_server() -> impl IntoResponse {
525525
authorization_endpoint: format!("http://{}/oauth/authorize", BIND_ADDRESS),
526526
token_endpoint: format!("http://{}/oauth/token", BIND_ADDRESS),
527527
scopes_supported: Some(vec!["profile".to_string(), "email".to_string()]),
528-
registration_endpoint: format!("http://{}/oauth/register", BIND_ADDRESS),
528+
registration_endpoint: Some(format!("http://{}/oauth/register", BIND_ADDRESS)),
529529
issuer: Some(BIND_ADDRESS.to_string()),
530530
jwks_uri: Some(format!("http://{}/oauth/jwks", BIND_ADDRESS)),
531531
additional_fields,

0 commit comments

Comments
 (0)