Allow redirect url path when user signs in #316

Open
reda wants to merge 3 commits from feat/auth-add-next-url-redirect into master
8 changed files with 44 additions and 27 deletions

View File

@@ -1,7 +0,0 @@
FLEET_AUTH_ISSUER_URL=
FLEET_AUTH_AUTHORIZE_URL=
FLEET_AUTH_TOKEN_URL=
FLEET_AUTH_CLIENT_ID=
FLEET_AUTH_REDIRECT_URI=
FLEET_AUTH_SCOPE=
FLEET_AUTH_TRUSTED_AUDIENCES=

View File

@@ -759,7 +759,7 @@ pub async fn mint_access_token(
access_token: String,
}
let tr: TokenResponse = resp.json().await.context("parse token response")?;
if std::env::var("FLEET_AUTH_CALLOUT_DEBUG_TOKENS").is_ok()
if std::env::var("HARMONY_SSO_CALLOUT_DEBUG_TOKENS").is_ok()
&& let Some(payload_b64) = tr.access_token.split('.').nth(1)
{
use base64::Engine;

View File

@@ -1,12 +1,12 @@
#!/bin/bash
export BASE_URL=http://localhost:18080
export FLEET_AUTH_ZITADEL_BASE=https://sso-stg.cb1.nationtech.io
export FLEET_AUTH_CLIENT_ID=372626218874372917
export FLEET_AUTH_SCOPE="openid profile email"
export FLEET_AUTH_LOGOUT_REDIRECT_URI="http://localhost:18080/"
export FLEET_OPERATOR_COOKIE_KEY_B64=6eKVpj88jwIcmaJajPfohdaIXhSPlfYCrHaOfymTcIWBAIadvhg7NHpMo5vPSMy90vac3cq2liWe1naSgkbaYg==
export FLEET_AUTH_TRUSTED_AUDIENCES=371639797493596981,371683318111994677,372626218874372917,371639797157987125
export HARMONY_SSO_ZITADEL_BASE=https://sso-stg.cb1.nationtech.io
export HARMONY_SSO_CLIENT_ID=372626218874372917
export HARMONY_SSO_SCOPE="openid profile email"
export HARMONY_SSO_LOGOUT_REDIRECT_URI="http://localhost:18080/"
export HARMONY_COOKIE_KEY_B64=6eKVpj88jwIcmaJajPfohdaIXhSPlfYCrHaOfymTcIWBAIadvhg7NHpMo5vPSMy90vac3cq2liWe1naSgkbaYg==
export HARMONY_SSO_TRUSTED_AUDIENCES=371639797493596981,371683318111994677,372626218874372917,371639797157987125
export BASE_URL=http://localhost:18080
export RUST_LOG=debug

View File

@@ -9,8 +9,8 @@ use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use crate::config::ZitadelAuthConfig;
use crate::jwks::JwksCache;
use crate::login::{
AuthCallbackQuery, RawAuthCallbackQuery, TokenResponse, build_login_attempt, build_logout_url,
exchange_code_for_token, jwt_exp, validate_callback_state,
AuthCallbackQuery, LoginQuery, RawAuthCallbackQuery, TokenResponse, build_login_attempt,
build_logout_url, exchange_code_for_token, jwt_exp, valid_next, validate_callback_state,
};
use crate::session::LoginAttemptCookie;
@@ -23,8 +23,9 @@ pub const HARMONY_SESSION_COOKIE: &str = "harmony_fleet_session";
pub async fn login_handler(
jar: PrivateCookieJar,
State(config): State<ZitadelAuthConfig>,
Query(query): Query<LoginQuery>,
) -> Response {
match build_login_response(jar, &config) {
match build_login_response(jar, &config, query) {
Ok(r) => r.into_response(),
Err(e) => auth_error_response(e),
}
@@ -33,9 +34,16 @@ pub async fn login_handler(
fn build_login_response(
jar: PrivateCookieJar,
config: &ZitadelAuthConfig,
query: LoginQuery,
) -> Result<impl IntoResponse> {
let attempt = build_login_attempt(config)?;
let cookie_payload = LoginAttemptCookie::from(&attempt);
let mut cookie_payload = LoginAttemptCookie::from(&attempt);
cookie_payload.next = Some(
query
.next
.filter(|next| valid_next(next))
.unwrap_or_else(|| "/".to_string()),
);
let cookie_value = URL_SAFE_NO_PAD.encode(serde_json::to_vec(&cookie_payload)?);
let mut builder = Cookie::build((LOGIN_ATTEMPT_COOKIE, cookie_value))
@@ -113,7 +121,12 @@ async fn build_callback_response(
}
let session_jar = session_jar.add(session_cookie(&tokens, config));
Ok((jar, session_jar, Redirect::to("/")).into_response())
let next = attempt
.next
.as_deref()
.filter(|next| valid_next(next))
.unwrap_or("/");
Ok((jar, session_jar, Redirect::to(next)).into_response())
}
AuthCallbackQuery::Failure {
error,

View File

@@ -33,13 +33,13 @@ impl ZitadelAuthConfig {
}
}
pub const ZITADEL_BASE_ENV: &str = "FLEET_AUTH_ZITADEL_BASE";
pub const ZITADEL_BASE_ENV: &str = "HARMONY_SSO_ZITADEL_BASE";
pub const BASE_URL_ENV: &str = "BASE_URL";
pub const CLIENT_ID_ENV: &str = "FLEET_AUTH_CLIENT_ID";
pub const SCOPE_ENV: &str = "FLEET_AUTH_SCOPE";
pub const TRUSTED_AUDIENCES_ENV: &str = "FLEET_AUTH_TRUSTED_AUDIENCES";
pub const LOGOUT_REDIRECT_URI_ENV: &str = "FLEET_AUTH_LOGOUT_REDIRECT_URI";
pub const COOKIE_KEY_ENV: &str = "FLEET_OPERATOR_COOKIE_KEY_B64";
pub const CLIENT_ID_ENV: &str = "HARMONY_SSO_CLIENT_ID";
pub const SCOPE_ENV: &str = "HARMONY_SSO_SCOPE";
pub const TRUSTED_AUDIENCES_ENV: &str = "HARMONY_SSO_TRUSTED_AUDIENCES";
pub const LOGOUT_REDIRECT_URI_ENV: &str = "HARMONY_SSO_LOGOUT_REDIRECT_URI";
pub const COOKIE_KEY_ENV: &str = "HARMONY_COOKIE_KEY_B64";
pub fn config_from_env() -> ZitadelAuthConfig {
ZitadelAuthConfig {

View File

@@ -15,9 +15,9 @@ pub use config::{
pub use jwks::JwksCache;
pub use login::{
AuthCallbackQuery, LoginAttempt, RawAuthCallbackQuery, TokenResponse, ValidatedUser,
AuthCallbackQuery, LoginAttempt, LoginQuery, RawAuthCallbackQuery, TokenResponse, ValidatedUser,
build_login_attempt, build_logout_url, exchange_code_for_token, jwt_exp,
validate_callback_state, validate_id_token,
valid_next, validate_callback_state, validate_id_token,
};
pub use session::{LoginAttemptCookie, VerifiedSession};

View File

@@ -37,6 +37,11 @@ pub struct TokenResponse {
pub expires_in: Option<u64>,
}
#[derive(Debug, Deserialize)]
pub struct LoginQuery {
pub next: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct RawAuthCallbackQuery {
pub code: Option<String>,
@@ -63,10 +68,15 @@ impl From<&LoginAttempt> for LoginAttemptCookie {
state: attempt.state.clone(),
pkce_code_verifier: attempt.pkce_code_verifier.clone(),
nonce: attempt.nonce.clone(),
next: None,
}
}
}
pub fn valid_next(next: &str) -> bool {
next.starts_with('/') && !next.starts_with("//") && !next.chars().any(char::is_control)
}
impl TryFrom<RawAuthCallbackQuery> for AuthCallbackQuery {
type Error = anyhow::Error;

View File

@@ -18,4 +18,5 @@ pub struct LoginAttemptCookie {
pub state: String,
pub pkce_code_verifier: String,
pub nonce: String,
pub next: Option<String>,
}