Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-10-03 22:43:56 +02:00
Allow to cache discovery endpoint
Dieser Commit ist enthalten in:
Ursprung
ec764adb2c
Commit
83ff5cc892
4 geänderte Dateien mit 26 neuen und 11 gelöschten Zeilen
|
@ -445,6 +445,8 @@
|
||||||
# SSO_MASTER_PASSWORD_POLICY='{"enforceOnLogin":false,"minComplexity":3,"minLength":12,"requireLower":false,"requireNumbers":false,"requireSpecial":false,"requireUpper":false}'
|
# SSO_MASTER_PASSWORD_POLICY='{"enforceOnLogin":false,"minComplexity":3,"minLength":12,"requireLower":false,"requireNumbers":false,"requireSpecial":false,"requireUpper":false}'
|
||||||
## Use sso only for authentication not the session lifecycle
|
## Use sso only for authentication not the session lifecycle
|
||||||
# SSO_AUTH_ONLY_NOT_SESSION=false
|
# SSO_AUTH_ONLY_NOT_SESSION=false
|
||||||
|
## Client cache for discovery endpoint. Duration in seconds (0 to disable).
|
||||||
|
# SSO_CLIENT_CACHE_EXPIRATION=0
|
||||||
## Log all the tokens, LOG_LEVEL=debug is required
|
## Log all the tokens, LOG_LEVEL=debug is required
|
||||||
# SSO_DEBUG_TOKENS=false
|
# SSO_DEBUG_TOKENS=false
|
||||||
|
|
||||||
|
|
1
SSO.md
1
SSO.md
|
@ -26,6 +26,7 @@ The following configurations are available
|
||||||
- `SSO_CLIENT_SECRET` : Client Secret
|
- `SSO_CLIENT_SECRET` : Client Secret
|
||||||
- `SSO_MASTER_PASSWORD_POLICY`: Optional Master password policy
|
- `SSO_MASTER_PASSWORD_POLICY`: Optional Master password policy
|
||||||
- `SSO_AUTH_ONLY_NOT_SESSION`: Enable to use SSO only for authentication not session lifecycle
|
- `SSO_AUTH_ONLY_NOT_SESSION`: Enable to use SSO only for authentication not session lifecycle
|
||||||
|
- `SSO_CLIENT_CACHE_EXPIRATION`: Cache calls to the discovery endpoint, duration in seconds, `0` to disable (default `0`);
|
||||||
- `SSO_DEBUG_TOKENS`: Log all tokens (default `false`, `LOG_LEVEL=debug` is required)
|
- `SSO_DEBUG_TOKENS`: Log all tokens (default `false`, `LOG_LEVEL=debug` is required)
|
||||||
|
|
||||||
The callback url is : `https://your.domain/identity/connect/oidc-signin`
|
The callback url is : `https://your.domain/identity/connect/oidc-signin`
|
||||||
|
|
|
@ -636,6 +636,8 @@ make_config! {
|
||||||
sso_master_password_policy: String, true, option;
|
sso_master_password_policy: String, true, option;
|
||||||
/// Use sso only for auth not the session lifecycle
|
/// Use sso only for auth not the session lifecycle
|
||||||
sso_auth_only_not_session: bool, true, def, false;
|
sso_auth_only_not_session: bool, true, def, false;
|
||||||
|
/// Client cache for discovery endpoint. Duration in seconds (0 or less to disable).
|
||||||
|
sso_client_cache_expiration: u64, true, def, 0;
|
||||||
/// Log all tokens, LOG_LEVEL=debug is required
|
/// Log all tokens, LOG_LEVEL=debug is required
|
||||||
sso_debug_tokens: bool, true, def, false;
|
sso_debug_tokens: bool, true, def, false;
|
||||||
},
|
},
|
||||||
|
|
32
src/sso.rs
32
src/sso.rs
|
@ -1,7 +1,6 @@
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::sync::RwLock;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -31,7 +30,10 @@ use crate::{
|
||||||
static AC_CACHE: Lazy<Cache<String, AuthenticatedUser>> =
|
static AC_CACHE: Lazy<Cache<String, AuthenticatedUser>> =
|
||||||
Lazy::new(|| Cache::builder().max_capacity(1000).time_to_live(Duration::from_secs(10 * 60)).build());
|
Lazy::new(|| Cache::builder().max_capacity(1000).time_to_live(Duration::from_secs(10 * 60)).build());
|
||||||
|
|
||||||
static CLIENT_CACHE: RwLock<Option<CoreClient>> = RwLock::new(None);
|
static CLIENT_CACHE_KEY: Lazy<String> = Lazy::new(|| "sso-client".to_string());
|
||||||
|
static CLIENT_CACHE: Lazy<Cache<String, CoreClient>> = Lazy::new(|| {
|
||||||
|
Cache::builder().max_capacity(1).time_to_live(Duration::from_secs(CONFIG.sso_client_cache_expiration())).build()
|
||||||
|
});
|
||||||
|
|
||||||
static SSO_JWT_ISSUER: Lazy<String> = Lazy::new(|| format!("{}|sso", CONFIG.domain_origin()));
|
static SSO_JWT_ISSUER: Lazy<String> = Lazy::new(|| format!("{}|sso", CONFIG.domain_origin()));
|
||||||
|
|
||||||
|
@ -165,14 +167,17 @@ impl CoreClientExt for CoreClient {
|
||||||
|
|
||||||
// Simple cache to prevent recalling the discovery endpoint each time
|
// Simple cache to prevent recalling the discovery endpoint each time
|
||||||
async fn cached() -> ApiResult<CoreClient> {
|
async fn cached() -> ApiResult<CoreClient> {
|
||||||
let cc_client = CLIENT_CACHE.read().ok().and_then(|rw_lock| rw_lock.clone());
|
if CONFIG.sso_client_cache_expiration() > 0 {
|
||||||
match cc_client {
|
match CLIENT_CACHE.get(&*CLIENT_CACHE_KEY) {
|
||||||
Some(client) => Ok(client),
|
Some(client) => Ok(client),
|
||||||
None => Self::_get_client().await.map(|client| {
|
None => Self::_get_client().await.map(|client| {
|
||||||
let mut cached_client = CLIENT_CACHE.write().unwrap();
|
debug!("Inserting new client in cache");
|
||||||
*cached_client = Some(client.clone());
|
CLIENT_CACHE.insert(CLIENT_CACHE_KEY.clone(), client.clone());
|
||||||
client
|
client
|
||||||
}),
|
}),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Self::_get_client().await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,8 +351,13 @@ pub async fn exchange_code(wrapped_code: &str, conn: &mut DbConn) -> ApiResult<U
|
||||||
}
|
}
|
||||||
|
|
||||||
let id_claims = match id_token.claims(&client.vw_id_token_verifier(), &oidc_nonce) {
|
let id_claims = match id_token.claims(&client.vw_id_token_verifier(), &oidc_nonce) {
|
||||||
Err(err) => err!(format!("Could not read id_token claims, {err}")),
|
|
||||||
Ok(claims) => claims,
|
Ok(claims) => claims,
|
||||||
|
Err(err) => {
|
||||||
|
if CONFIG.sso_client_cache_expiration() > 0 {
|
||||||
|
CLIENT_CACHE.invalidate(&*CLIENT_CACHE_KEY);
|
||||||
|
}
|
||||||
|
err!(format!("Could not read id_token claims, {err}"));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let email = match id_claims.email() {
|
let email = match id_claims.email() {
|
||||||
|
|
Laden …
In neuem Issue referenzieren