Minor fixes for oidc with single page applications (#2420)

This commit is contained in:
Firstyear 2024-01-09 09:57:14 +10:00 committed by GitHub
parent 55841b7eef
commit 0e44cc1dcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 8 deletions

View file

@ -19,7 +19,7 @@ use kanidm_proto::constants::uri::{
OAUTH2_AUTHORISE, OAUTH2_AUTHORISE_PERMIT, OAUTH2_AUTHORISE_REJECT, OAUTH2_AUTHORISE, OAUTH2_AUTHORISE_PERMIT, OAUTH2_AUTHORISE_REJECT,
}; };
use kanidm_proto::constants::APPLICATION_JSON; use kanidm_proto::constants::APPLICATION_JSON;
use kanidm_proto::oauth2::{AccessTokenResponse, AuthorisationResponse, OidcDiscoveryResponse}; use kanidm_proto::oauth2::AuthorisationResponse;
use kanidmd_lib::idm::oauth2::{ use kanidmd_lib::idm::oauth2::{
AccessTokenIntrospectRequest, AccessTokenRequest, AuthorisationRequest, AuthorisePermitSuccess, AccessTokenIntrospectRequest, AccessTokenRequest, AuthorisationRequest, AuthorisePermitSuccess,
AuthoriseResponse, ErrorResponse, Oauth2Error, TokenRevokeRequest, AuthoriseResponse, ErrorResponse, Oauth2Error, TokenRevokeRequest,
@ -483,7 +483,7 @@ pub async fn oauth2_token_post(
Extension(kopid): Extension<KOpId>, Extension(kopid): Extension<KOpId>,
headers: HeaderMap, headers: HeaderMap,
Form(tok_req): Form<AccessTokenRequest>, Form(tok_req): Form<AccessTokenRequest>,
) -> Result<Json<AccessTokenResponse>, HTTPOauth2Error> { ) -> impl IntoResponse {
// This is called directly by the resource server, where we then issue // This is called directly by the resource server, where we then issue
// the token to the caller. // 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) .handle_oauth2_token_exchange(client_authz, tok_req, kopid.eventid)
.await .await
{ {
Ok(tok_res) => Ok(Json(tok_res)), Ok(tok_res) => (
Err(e) => Err(HTTPOauth2Error(e)), 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<ServerState>, State(state): State<ServerState>,
Path(client_id): Path<String>, Path(client_id): Path<String>,
Extension(kopid): Extension<KOpId>, Extension(kopid): Extension<KOpId>,
) -> Result<Json<OidcDiscoveryResponse>, Response> { ) -> impl IntoResponse {
// let client_id = req.get_url_param("client_id")?; // let client_id = req.get_url_param("client_id")?;
let res = state let res = state
@ -522,10 +527,15 @@ pub async fn oauth2_openid_discovery_get(
.await; .await;
match res { match res {
Ok(dsc) => Ok(Json(dsc)), Ok(dsc) => (
StatusCode::OK,
[(ACCESS_CONTROL_ALLOW_ORIGIN, "*")],
Json(dsc),
)
.into_response(),
Err(e) => { Err(e) => {
error!(err = ?e, "Unable to access discovery info"); 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<ServerState> {
) )
// ⚠️ ⚠️ WARNING ⚠️ ⚠️ // ⚠️ ⚠️ WARNING ⚠️ ⚠️
// IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS // 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 ⚠️ ⚠️ // ⚠️ ⚠️ WARNING ⚠️ ⚠️
// IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS // IF YOU CHANGE THESE VALUES YOU MUST UPDATE OIDC DISCOVERY URLS
.route( .route(

View file

@ -163,6 +163,16 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
.expect("Failed to send request."); .expect("Failed to send request.");
assert!(response.status() == reqwest::StatusCode::OK); 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); assert_no_cache!(response);
let discovery: OidcDiscoveryResponse = 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."); .expect("Failed to send code exchange request.");
assert!(response.status() == reqwest::StatusCode::OK); 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!( assert!(
response.headers().get(CONTENT_TYPE) == Some(&HeaderValue::from_static(APPLICATION_JSON)) response.headers().get(CONTENT_TYPE) == Some(&HeaderValue::from_static(APPLICATION_JSON))
); );