fix(examples): Make mcp_oauth_server example worked in MCP inspector OAuth (#219)
This commit is contained in:
parent
22134eb33e
commit
23e8200a58
2 changed files with 34 additions and 7 deletions
|
|
@ -27,6 +27,7 @@ chrono = "0.4"
|
||||||
uuid = { version = "1.6", features = ["v4", "serde"] }
|
uuid = { version = "1.6", features = ["v4", "serde"] }
|
||||||
serde_urlencoded = "0.7"
|
serde_urlencoded = "0.7"
|
||||||
askama = { version = "0.14"}
|
askama = { version = "0.14"}
|
||||||
|
tower-http = { version = "0.6", features = ["cors"] }
|
||||||
|
|
||||||
# [dev-dependencies.'cfg(target_arch="linux")'.dependencies]
|
# [dev-dependencies.'cfg(target_arch="linux")'.dependencies]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,10 @@ use rmcp::transport::{
|
||||||
sse_server::SseServerConfig,
|
sse_server::SseServerConfig,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
use tower_http::cors::{Any, CorsLayer};
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
@ -518,6 +520,15 @@ async fn validate_token_middleware(
|
||||||
|
|
||||||
// handle oauth server metadata request
|
// handle oauth server metadata request
|
||||||
async fn oauth_authorization_server() -> impl IntoResponse {
|
async fn oauth_authorization_server() -> impl IntoResponse {
|
||||||
|
let mut additional_fields = HashMap::new();
|
||||||
|
additional_fields.insert(
|
||||||
|
"response_types_supported".into(),
|
||||||
|
Value::Array(vec![Value::String("code".into())]),
|
||||||
|
);
|
||||||
|
additional_fields.insert(
|
||||||
|
"code_challenge_methods_supported".into(),
|
||||||
|
Value::Array(vec![Value::String("S256".into())]),
|
||||||
|
);
|
||||||
let metadata = AuthorizationMetadata {
|
let metadata = AuthorizationMetadata {
|
||||||
authorization_endpoint: format!("http://{}/oauth/authorize", BIND_ADDRESS),
|
authorization_endpoint: format!("http://{}/oauth/authorize", BIND_ADDRESS),
|
||||||
token_endpoint: format!("http://{}/oauth/token", BIND_ADDRESS),
|
token_endpoint: format!("http://{}/oauth/token", BIND_ADDRESS),
|
||||||
|
|
@ -525,7 +536,7 @@ async fn oauth_authorization_server() -> impl IntoResponse {
|
||||||
registration_endpoint: format!("http://{}/oauth/register", BIND_ADDRESS),
|
registration_endpoint: format!("http://{}/oauth/register", BIND_ADDRESS),
|
||||||
issuer: Some(BIND_ADDRESS.to_string()),
|
issuer: Some(BIND_ADDRESS.to_string()),
|
||||||
jwks_uri: Some(format!("http://{}/oauth/jwks", BIND_ADDRESS)),
|
jwks_uri: Some(format!("http://{}/oauth/jwks", BIND_ADDRESS)),
|
||||||
additional_fields: HashMap::new(),
|
additional_fields,
|
||||||
};
|
};
|
||||||
debug!("metadata: {:?}", metadata);
|
debug!("metadata: {:?}", metadata);
|
||||||
(StatusCode::OK, Json(metadata))
|
(StatusCode::OK, Json(metadata))
|
||||||
|
|
@ -655,18 +666,33 @@ async fn main() -> Result<()> {
|
||||||
validate_token_middleware,
|
validate_token_middleware,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// Create CORS layer for the oauth authorization server endpoint
|
||||||
|
let cors_layer = CorsLayer::new()
|
||||||
|
.allow_origin(Any)
|
||||||
|
.allow_methods(Any)
|
||||||
|
.allow_headers(Any);
|
||||||
|
|
||||||
|
// Create a sub-router for the oauth authorization server endpoint with CORS
|
||||||
|
let oauth_server_router = Router::new()
|
||||||
|
.route(
|
||||||
|
"/.well-known/oauth-authorization-server",
|
||||||
|
get(oauth_authorization_server).options(oauth_authorization_server),
|
||||||
|
)
|
||||||
|
.route("/oauth/token", post(oauth_token).options(oauth_token))
|
||||||
|
.route(
|
||||||
|
"/oauth/register",
|
||||||
|
post(oauth_register).options(oauth_register),
|
||||||
|
)
|
||||||
|
.layer(cors_layer)
|
||||||
|
.with_state(oauth_store.clone());
|
||||||
|
|
||||||
// Create HTTP router with request logging middleware
|
// Create HTTP router with request logging middleware
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.route("/mcp", get(index))
|
.route("/mcp", get(index))
|
||||||
.route(
|
|
||||||
"/.well-known/oauth-authorization-server",
|
|
||||||
get(oauth_authorization_server),
|
|
||||||
)
|
|
||||||
.route("/oauth/authorize", get(oauth_authorize))
|
.route("/oauth/authorize", get(oauth_authorize))
|
||||||
.route("/oauth/approve", post(oauth_approve))
|
.route("/oauth/approve", post(oauth_approve))
|
||||||
.route("/oauth/token", post(oauth_token))
|
.merge(oauth_server_router) // Merge the CORS-enabled oauth server router
|
||||||
.route("/oauth/register", post(oauth_register))
|
|
||||||
// .merge(protected_sse_router)
|
// .merge(protected_sse_router)
|
||||||
.with_state(oauth_store.clone())
|
.with_state(oauth_store.clone())
|
||||||
.layer(middleware::from_fn(log_request));
|
.layer(middleware::from_fn(log_request));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue