From a818cebc858478761d71ee429ad955efd1a91480 Mon Sep 17 00:00:00 2001 From: Firstyear Date: Sun, 9 Jul 2023 12:06:40 +1000 Subject: [PATCH] Add preflight headers (#1829) --- server/core/src/https/oauth2.rs | 14 ++++++++-- server/testkit/tests/oauth2_test.rs | 40 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/server/core/src/https/oauth2.rs b/server/core/src/https/oauth2.rs index 32888dc51..6afcbd873 100644 --- a/server/core/src/https/oauth2.rs +++ b/server/core/src/https/oauth2.rs @@ -856,6 +856,16 @@ pub async fn oauth2_token_revoke_post( } } +// Some requests from browsers require preflight so that CORS works. +pub async fn oauth2_preflight_options() -> impl IntoResponse { + #[allow(clippy::unwrap_used)] + Response::builder() + .status(StatusCode::OK) + .header(ACCESS_CONTROL_ALLOW_ORIGIN, "*") + .body(Body::empty()) + .unwrap() +} + pub fn oauth2_route_setup(state: ServerState) -> Router { // this has all the openid-related routes let openid_router = Router::new() @@ -863,13 +873,13 @@ pub fn oauth2_route_setup(state: ServerState) -> Router { // // IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS .route( "/oauth2/openid/:client_id/.well-known/openid-configuration", - get(oauth2_openid_discovery_get), + get(oauth2_openid_discovery_get).options(oauth2_preflight_options), ) // // ⚠️ ⚠️ WARNING ⚠️ ⚠️ // // IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS .route( "/oauth2/openid/:client_id/userinfo", - get(oauth2_openid_userinfo_get), + get(oauth2_openid_userinfo_get).options(oauth2_preflight_options), ) // // ⚠️ ⚠️ WARNING ⚠️ ⚠️ // // IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS diff --git a/server/testkit/tests/oauth2_test.rs b/server/testkit/tests/oauth2_test.rs index 5ee2a89bc..7307e9e47 100644 --- a/server/testkit/tests/oauth2_test.rs +++ b/server/testkit/tests/oauth2_test.rs @@ -132,6 +132,27 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) { .expect("Failed to create client."); // Step 0 - get the openid discovery details and the public key. + let response = client + .request( + reqwest::Method::OPTIONS, + format!( + "{}/oauth2/openid/test_integration/.well-known/openid-configuration", + url + ), + ) + .send() + .await + .expect("Failed to send discovery preflight request."); + + assert!(response.status() == reqwest::StatusCode::OK); + let cors_header: &str = response + .headers() + .get("access-control-allow-origin") + .expect("missing access-control-allow-origin header") + .to_str() + .expect("invalid access-control-allow-origin header"); + assert!(cors_header.eq("*")); + let response = client .get(format!( "{}/oauth2/openid/test_integration/.well-known/openid-configuration", @@ -607,6 +628,25 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) { assert!(oidc.s_claims.email.as_deref() == Some("oauth_test@localhost")); assert!(oidc.s_claims.email_verified == Some(true)); + // Check the preflight works. + let response = client + .request( + reqwest::Method::OPTIONS, + format!("{}/oauth2/openid/test_integration/userinfo", url), + ) + .send() + .await + .expect("Failed to send userinfo preflight request."); + + assert!(response.status() == reqwest::StatusCode::OK); + let cors_header: &str = response + .headers() + .get("access-control-allow-origin") + .expect("missing access-control-allow-origin header") + .to_str() + .expect("invalid access-control-allow-origin header"); + assert!(cors_header.eq("*")); + let response = client .get(format!("{}/oauth2/openid/test_integration/userinfo", url)) .bearer_auth(atr.access_token.clone())