diff --git a/server/core/src/https/oauth2.rs b/server/core/src/https/oauth2.rs index 606ce4310..7feb07a8b 100644 --- a/server/core/src/https/oauth2.rs +++ b/server/core/src/https/oauth2.rs @@ -19,7 +19,7 @@ use kanidm_proto::constants::uri::{ OAUTH2_AUTHORISE, OAUTH2_AUTHORISE_PERMIT, OAUTH2_AUTHORISE_REJECT, }; use kanidm_proto::constants::APPLICATION_JSON; -use kanidm_proto::oauth2::{AccessTokenResponse, AuthorisationResponse, OidcDiscoveryResponse}; +use kanidm_proto::oauth2::AuthorisationResponse; use kanidmd_lib::idm::oauth2::{ AccessTokenIntrospectRequest, AccessTokenRequest, AuthorisationRequest, AuthorisePermitSuccess, AuthoriseResponse, ErrorResponse, Oauth2Error, TokenRevokeRequest, @@ -483,7 +483,7 @@ pub async fn oauth2_token_post( Extension(kopid): Extension, headers: HeaderMap, Form(tok_req): Form, -) -> Result, HTTPOauth2Error> { +) -> impl IntoResponse { // This is called directly by the resource server, where we then issue // the token to the caller. @@ -503,8 +503,13 @@ pub async fn oauth2_token_post( .handle_oauth2_token_exchange(client_authz, tok_req, kopid.eventid) .await { - Ok(tok_res) => Ok(Json(tok_res)), - Err(e) => Err(HTTPOauth2Error(e)), + Ok(tok_res) => ( + StatusCode::OK, + [(ACCESS_CONTROL_ALLOW_ORIGIN, "*")], + Json(tok_res), + ) + .into_response(), + Err(e) => HTTPOauth2Error(e).into_response(), } } @@ -513,7 +518,7 @@ pub async fn oauth2_openid_discovery_get( State(state): State, Path(client_id): Path, Extension(kopid): Extension, -) -> Result, Response> { +) -> impl IntoResponse { // let client_id = req.get_url_param("client_id")?; let res = state @@ -522,10 +527,15 @@ pub async fn oauth2_openid_discovery_get( .await; match res { - Ok(dsc) => Ok(Json(dsc)), + Ok(dsc) => ( + StatusCode::OK, + [(ACCESS_CONTROL_ALLOW_ORIGIN, "*")], + Json(dsc), + ) + .into_response(), Err(e) => { error!(err = ?e, "Unable to access discovery info"); - Err(WebError::from(e).response_with_access_control_origin_header()) + WebError::from(e).response_with_access_control_origin_header() } } } @@ -772,7 +782,10 @@ pub fn route_setup(state: ServerState) -> Router { ) // ⚠️ ⚠️ WARNING ⚠️ ⚠️ // IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS - .route("/oauth2/token", post(oauth2_token_post)) + .route( + "/oauth2/token", + post(oauth2_token_post).options(oauth2_preflight_options), + ) // ⚠️ ⚠️ WARNING ⚠️ ⚠️ // IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS .route( diff --git a/server/testkit/tests/oauth2_test.rs b/server/testkit/tests/oauth2_test.rs index 1118737fe..bcd1a29e1 100644 --- a/server/testkit/tests/oauth2_test.rs +++ b/server/testkit/tests/oauth2_test.rs @@ -163,6 +163,16 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) { .expect("Failed to send request."); assert!(response.status() == reqwest::StatusCode::OK); + + // Assert CORS on the GET too. + let cors_header: &str = response + .headers() + .get(http::header::ACCESS_CONTROL_ALLOW_ORIGIN) + .expect("missing access-control-allow-origin header") + .to_str() + .expect("invalid access-control-allow-origin header"); + assert!(cors_header.eq("*")); + assert_no_cache!(response); let discovery: OidcDiscoveryResponse = response @@ -306,6 +316,15 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) { .expect("Failed to send code exchange request."); assert!(response.status() == reqwest::StatusCode::OK); + + let cors_header: &str = response + .headers() + .get(http::header::ACCESS_CONTROL_ALLOW_ORIGIN) + .expect("missing access-control-allow-origin header") + .to_str() + .expect("invalid access-control-allow-origin header"); + assert!(cors_header.eq("*")); + assert!( response.headers().get(CONTENT_TYPE) == Some(&HeaderValue::from_static(APPLICATION_JSON)) );