Skip to content

Commit f9d477f

Browse files
committed
Refactor OIDC cookie handling to introduce a constant for cookie expiration and simplify nonce validation logic
1 parent 0f5ff8c commit f9d477f

File tree

1 file changed

+10
-23
lines changed

1 file changed

+10
-23
lines changed

src/webserver/oidc.rs

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use actix_web::{
1717
};
1818
use anyhow::{anyhow, Context};
1919
use awc::Client;
20-
use chrono::Utc;
2120
use openidconnect::core::{
2221
CoreAuthDisplay, CoreAuthPrompt, CoreErrorResponseType, CoreGenderClaim, CoreJsonWebKey,
2322
CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm, CoreRevocableToken,
@@ -45,6 +44,8 @@ const SQLPAGE_NONCE_COOKIE_NAME: &str = "sqlpage_oidc_nonce";
4544
const SQLPAGE_REDIRECT_URL_COOKIE_PREFIX: &str = "sqlpage_oidc_redirect_url_";
4645
const OIDC_CLIENT_MAX_REFRESH_INTERVAL: Duration = Duration::from_secs(60 * 60);
4746
const OIDC_CLIENT_MIN_REFRESH_INTERVAL: Duration = Duration::from_secs(5);
47+
const AUTH_COOKIE_EXPIRATION: awc::cookie::time::Duration =
48+
actix_web::cookie::time::Duration::days(7);
4849

4950
#[derive(Clone, Debug, Serialize, Deserialize)]
5051
#[serde(transparent)]
@@ -211,7 +212,7 @@ impl OidcState {
211212
async fn get_token_claims(
212213
&self,
213214
id_token: OidcToken,
214-
expected_nonce: Option<&Nonce>,
215+
expected_nonce: &Nonce,
215216
) -> anyhow::Result<OidcClaims> {
216217
let client = &self.get_client().await;
217218
let verifier = self.config.create_id_token_verifier(client);
@@ -452,9 +453,7 @@ async fn process_oidc_callback(
452453
let redirect_target = validate_redirect_url(redirect_url_cookie.value().to_string());
453454
log::info!("Redirecting to {redirect_target} after a successful login");
454455
let mut response = build_redirect_response(redirect_target);
455-
set_auth_cookie(&mut response, &token_response, oidc_state)
456-
.await
457-
.context("Failed to set auth cookie")?;
456+
set_auth_cookie(&mut response, &token_response).context("Failed to set auth cookie")?;
458457

459458
// Clean up the state-specific cookie after successful authentication
460459
response.add_removal_cookie(&redirect_url_cookie)?;
@@ -477,21 +476,16 @@ async fn exchange_code_for_token(
477476
Ok(token_response)
478477
}
479478

480-
async fn set_auth_cookie(
479+
fn set_auth_cookie(
481480
response: &mut HttpResponse,
482481
token_response: &OidcTokenResponse,
483-
oidc_state: &OidcState,
484482
) -> anyhow::Result<()> {
485483
let access_token = token_response.access_token();
486484
log::trace!("Received access token: {}", access_token.secret());
487485
let id_token = token_response
488486
.id_token()
489487
.context("No ID token found in the token response. You may have specified an oauth2 provider that does not support OIDC.")?;
490488

491-
let claims_res = oidc_state.get_token_claims(id_token.clone(), None).await;
492-
let expiration = claims_res.context("Parsing ID token claims")?.expiration();
493-
let max_age_seconds = expiration.signed_duration_since(Utc::now()).num_seconds();
494-
495489
let id_token_str = id_token.to_string();
496490
log::trace!("Setting auth cookie: {SQLPAGE_AUTH_COOKIE_NAME}=\"{id_token_str}\"");
497491
let id_token_size_kb = id_token_str.len() / 1024;
@@ -504,7 +498,7 @@ async fn set_auth_cookie(
504498
let cookie = Cookie::build(SQLPAGE_AUTH_COOKIE_NAME, id_token_str)
505499
.secure(true)
506500
.http_only(true)
507-
.max_age(actix_web::cookie::time::Duration::seconds(max_age_seconds))
501+
.max_age(AUTH_COOKIE_EXPIRATION)
508502
.same_site(actix_web::cookie::SameSite::Lax)
509503
.path("/")
510504
.finish();
@@ -545,11 +539,9 @@ async fn get_authenticated_user_info(
545539
let id_token = OidcToken::from_str(&cookie_value)
546540
.with_context(|| format!("Invalid SQLPage auth cookie: {cookie_value:?}"))?;
547541

548-
// Try to get nonce from cookies if this is a callback request
549542
let nonce = get_nonce_from_cookie(request)?;
550-
551543
log::debug!("Verifying id token: {id_token:?}");
552-
let claims = oidc_state.get_token_claims(id_token, Some(&nonce)).await?;
544+
let claims = oidc_state.get_token_claims(id_token, &nonce).await?;
553545
log::debug!("The current user is: {claims:?}");
554546
Ok(Some(claims))
555547
}
@@ -750,15 +742,9 @@ fn hash_nonce(nonce: &Nonce) -> String {
750742
hash.to_string()
751743
}
752744

753-
fn check_nonce(
754-
id_token_nonce: Option<&Nonce>,
755-
expected_nonce: Option<&Nonce>,
756-
) -> Result<(), String> {
757-
let Some(expected) = expected_nonce else {
758-
return Ok(()); // No expected nonce, no validation needed
759-
};
745+
fn check_nonce(id_token_nonce: Option<&Nonce>, expected_nonce: &Nonce) -> Result<(), String> {
760746
match id_token_nonce {
761-
Some(id_token_nonce) => nonce_matches(id_token_nonce, expected),
747+
Some(id_token_nonce) => nonce_matches(id_token_nonce, expected_nonce),
762748
None => Err("No nonce found in the ID token".to_string()),
763749
}
764750
}
@@ -790,6 +776,7 @@ fn create_nonce_cookie(nonce: &Nonce) -> Cookie<'_> {
790776
.secure(true)
791777
.http_only(true)
792778
.same_site(actix_web::cookie::SameSite::Lax)
779+
.max_age(AUTH_COOKIE_EXPIRATION)
793780
.path("/")
794781
.finish()
795782
}

0 commit comments

Comments
 (0)