mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 13:30:39 +08:00
refactor(authn): Enable cookies in Integ (#6599)
This commit is contained in:
@ -403,6 +403,7 @@ two_factor_auth_expiry_in_secs = 300 # Number of seconds after which 2FA should
|
|||||||
totp_issuer_name = "Hyperswitch" # Name of the issuer for TOTP
|
totp_issuer_name = "Hyperswitch" # Name of the issuer for TOTP
|
||||||
base_url = "" # Base url used for user specific redirects and emails
|
base_url = "" # Base url used for user specific redirects and emails
|
||||||
force_two_factor_auth = false # Whether to force two factor authentication for all users
|
force_two_factor_auth = false # Whether to force two factor authentication for all users
|
||||||
|
force_cookies = true # Whether to use only cookies for JWT extraction and authentication
|
||||||
|
|
||||||
#tokenization configuration which describe token lifetime and payment method for specific connector
|
#tokenization configuration which describe token lifetime and payment method for specific connector
|
||||||
[tokenization]
|
[tokenization]
|
||||||
|
|||||||
@ -145,6 +145,7 @@ two_factor_auth_expiry_in_secs = 300
|
|||||||
totp_issuer_name = "Hyperswitch Integ"
|
totp_issuer_name = "Hyperswitch Integ"
|
||||||
base_url = "https://integ.hyperswitch.io"
|
base_url = "https://integ.hyperswitch.io"
|
||||||
force_two_factor_auth = false
|
force_two_factor_auth = false
|
||||||
|
force_cookies = true
|
||||||
|
|
||||||
[frm]
|
[frm]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|||||||
@ -152,6 +152,7 @@ two_factor_auth_expiry_in_secs = 300
|
|||||||
totp_issuer_name = "Hyperswitch Production"
|
totp_issuer_name = "Hyperswitch Production"
|
||||||
base_url = "https://live.hyperswitch.io"
|
base_url = "https://live.hyperswitch.io"
|
||||||
force_two_factor_auth = true
|
force_two_factor_auth = true
|
||||||
|
force_cookies = false
|
||||||
|
|
||||||
[frm]
|
[frm]
|
||||||
enabled = false
|
enabled = false
|
||||||
|
|||||||
@ -152,6 +152,7 @@ two_factor_auth_expiry_in_secs = 300
|
|||||||
totp_issuer_name = "Hyperswitch Sandbox"
|
totp_issuer_name = "Hyperswitch Sandbox"
|
||||||
base_url = "https://app.hyperswitch.io"
|
base_url = "https://app.hyperswitch.io"
|
||||||
force_two_factor_auth = false
|
force_two_factor_auth = false
|
||||||
|
force_cookies = false
|
||||||
|
|
||||||
[frm]
|
[frm]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|||||||
@ -329,6 +329,7 @@ two_factor_auth_expiry_in_secs = 300
|
|||||||
totp_issuer_name = "Hyperswitch Dev"
|
totp_issuer_name = "Hyperswitch Dev"
|
||||||
base_url = "http://localhost:8080"
|
base_url = "http://localhost:8080"
|
||||||
force_two_factor_auth = false
|
force_two_factor_auth = false
|
||||||
|
force_cookies = true
|
||||||
|
|
||||||
[bank_config.eps]
|
[bank_config.eps]
|
||||||
stripe = { banks = "arzte_und_apotheker_bank,austrian_anadi_bank_ag,bank_austria,bankhaus_carl_spangler,bankhaus_schelhammer_und_schattera_ag,bawag_psk_ag,bks_bank_ag,brull_kallmus_bank_ag,btv_vier_lander_bank,capital_bank_grawe_gruppe_ag,dolomitenbank,easybank_ag,erste_bank_und_sparkassen,hypo_alpeadriabank_international_ag,hypo_noe_lb_fur_niederosterreich_u_wien,hypo_oberosterreich_salzburg_steiermark,hypo_tirol_bank_ag,hypo_vorarlberg_bank_ag,hypo_bank_burgenland_aktiengesellschaft,marchfelder_bank,oberbank_ag,raiffeisen_bankengruppe_osterreich,schoellerbank_ag,sparda_bank_wien,volksbank_gruppe,volkskreditbank_ag,vr_bank_braunau" }
|
stripe = { banks = "arzte_und_apotheker_bank,austrian_anadi_bank_ag,bank_austria,bankhaus_carl_spangler,bankhaus_schelhammer_und_schattera_ag,bawag_psk_ag,bks_bank_ag,brull_kallmus_bank_ag,btv_vier_lander_bank,capital_bank_grawe_gruppe_ag,dolomitenbank,easybank_ag,erste_bank_und_sparkassen,hypo_alpeadriabank_international_ag,hypo_noe_lb_fur_niederosterreich_u_wien,hypo_oberosterreich_salzburg_steiermark,hypo_tirol_bank_ag,hypo_vorarlberg_bank_ag,hypo_bank_burgenland_aktiengesellschaft,marchfelder_bank,oberbank_ag,raiffeisen_bankengruppe_osterreich,schoellerbank_ag,sparda_bank_wien,volksbank_gruppe,volkskreditbank_ag,vr_bank_braunau" }
|
||||||
|
|||||||
@ -57,6 +57,7 @@ two_factor_auth_expiry_in_secs = 300
|
|||||||
totp_issuer_name = "Hyperswitch"
|
totp_issuer_name = "Hyperswitch"
|
||||||
base_url = "http://localhost:8080"
|
base_url = "http://localhost:8080"
|
||||||
force_two_factor_auth = false
|
force_two_factor_auth = false
|
||||||
|
force_cookies = true
|
||||||
|
|
||||||
[locker]
|
[locker]
|
||||||
host = ""
|
host = ""
|
||||||
|
|||||||
@ -557,6 +557,7 @@ pub struct UserSettings {
|
|||||||
pub totp_issuer_name: String,
|
pub totp_issuer_name: String,
|
||||||
pub base_url: String,
|
pub base_url: String,
|
||||||
pub force_two_factor_auth: bool,
|
pub force_two_factor_auth: bool,
|
||||||
|
pub force_cookies: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
|||||||
@ -294,7 +294,7 @@ pub async fn connect_account(
|
|||||||
|
|
||||||
pub async fn signout(
|
pub async fn signout(
|
||||||
state: SessionState,
|
state: SessionState,
|
||||||
user_from_token: auth::UserFromToken,
|
user_from_token: auth::UserIdFromAuth,
|
||||||
) -> UserResponse<()> {
|
) -> UserResponse<()> {
|
||||||
tfa_utils::delete_totp_from_redis(&state, &user_from_token.user_id).await?;
|
tfa_utils::delete_totp_from_redis(&state, &user_from_token.user_id).await?;
|
||||||
tfa_utils::delete_recovery_code_from_redis(&state, &user_from_token.user_id).await?;
|
tfa_utils::delete_recovery_code_from_redis(&state, &user_from_token.user_id).await?;
|
||||||
|
|||||||
@ -130,7 +130,7 @@ pub async fn signout(state: web::Data<AppState>, http_req: HttpRequest) -> HttpR
|
|||||||
&http_req,
|
&http_req,
|
||||||
(),
|
(),
|
||||||
|state, user, _, _| user_core::signout(state, user),
|
|state, user, _, _| user_core::signout(state, user),
|
||||||
&auth::DashboardNoPermissionAuth,
|
&auth::AnyPurposeOrLoginTokenAuth,
|
||||||
api_locking::LockAction::NotApplicable,
|
api_locking::LockAction::NotApplicable,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -871,6 +871,47 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "olap")]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AnyPurposeOrLoginTokenAuth;
|
||||||
|
|
||||||
|
#[cfg(feature = "olap")]
|
||||||
|
#[async_trait]
|
||||||
|
impl<A> AuthenticateAndFetch<UserIdFromAuth, A> for AnyPurposeOrLoginTokenAuth
|
||||||
|
where
|
||||||
|
A: SessionStateInfo + Sync,
|
||||||
|
{
|
||||||
|
async fn authenticate_and_fetch(
|
||||||
|
&self,
|
||||||
|
request_headers: &HeaderMap,
|
||||||
|
state: &A,
|
||||||
|
) -> RouterResult<(UserIdFromAuth, AuthenticationType)> {
|
||||||
|
let payload =
|
||||||
|
parse_jwt_payload::<A, SinglePurposeOrLoginToken>(request_headers, state).await?;
|
||||||
|
if payload.check_in_blacklist(state).await? {
|
||||||
|
return Err(errors::ApiErrorResponse::InvalidJwtToken.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let purpose_exists = payload.purpose.is_some();
|
||||||
|
let role_id_exists = payload.role_id.is_some();
|
||||||
|
|
||||||
|
if purpose_exists ^ role_id_exists {
|
||||||
|
Ok((
|
||||||
|
UserIdFromAuth {
|
||||||
|
user_id: payload.user_id.clone(),
|
||||||
|
},
|
||||||
|
AuthenticationType::SinglePurposeOrLoginJwt {
|
||||||
|
user_id: payload.user_id,
|
||||||
|
purpose: payload.purpose,
|
||||||
|
role_id: payload.role_id,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Err(errors::ApiErrorResponse::InvalidJwtToken.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct AdminApiAuth;
|
pub struct AdminApiAuth;
|
||||||
|
|
||||||
@ -2504,17 +2545,27 @@ where
|
|||||||
T: serde::de::DeserializeOwned,
|
T: serde::de::DeserializeOwned,
|
||||||
A: SessionStateInfo + Sync,
|
A: SessionStateInfo + Sync,
|
||||||
{
|
{
|
||||||
let token = match get_cookie_from_header(headers).and_then(cookies::parse_cookie) {
|
let cookie_token_result = get_cookie_from_header(headers).and_then(cookies::parse_cookie);
|
||||||
Ok(cookies) => cookies,
|
let auth_header_token_result = get_jwt_from_authorization_header(headers);
|
||||||
Err(error) => {
|
let force_cookie = state.conf().user.force_cookies;
|
||||||
let token = get_jwt_from_authorization_header(headers);
|
|
||||||
if token.is_err() {
|
logger::info!(
|
||||||
logger::error!(?error);
|
user_agent = ?headers.get(headers::USER_AGENT),
|
||||||
}
|
header_names = ?headers.keys().collect::<Vec<_>>(),
|
||||||
token?.to_owned()
|
is_token_equal =
|
||||||
}
|
auth_header_token_result.as_deref().ok() == cookie_token_result.as_deref().ok(),
|
||||||
|
cookie_error = ?cookie_token_result.as_ref().err(),
|
||||||
|
token_error = ?auth_header_token_result.as_ref().err(),
|
||||||
|
force_cookie,
|
||||||
|
);
|
||||||
|
|
||||||
|
let final_token = if force_cookie {
|
||||||
|
cookie_token_result?
|
||||||
|
} else {
|
||||||
|
auth_header_token_result?.to_owned()
|
||||||
};
|
};
|
||||||
decode_jwt(&token, state).await
|
|
||||||
|
decode_jwt(&final_token, state).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "v1")]
|
#[cfg(feature = "v1")]
|
||||||
|
|||||||
@ -36,6 +36,7 @@ password_validity_in_days = 90
|
|||||||
two_factor_auth_expiry_in_secs = 300
|
two_factor_auth_expiry_in_secs = 300
|
||||||
totp_issuer_name = "Hyperswitch"
|
totp_issuer_name = "Hyperswitch"
|
||||||
force_two_factor_auth = false
|
force_two_factor_auth = false
|
||||||
|
force_cookies = true
|
||||||
|
|
||||||
[locker]
|
[locker]
|
||||||
host = ""
|
host = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user