Allow redirect url path when user signs in #316
@@ -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=
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -18,4 +18,5 @@ pub struct LoginAttemptCookie {
|
||||
pub state: String,
|
||||
pub pkce_code_verifier: String,
|
||||
pub nonce: String,
|
||||
pub next: Option<String>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user