Can enforce 2FA for specific clients
This commit is contained in:
parent
64b1bd4de9
commit
cf0e7e1e68
@ -22,6 +22,8 @@ You can configure a list of clients (Relying Parties) in a `clients.yaml` file w
|
|||||||
default: true
|
default: true
|
||||||
# If you want the client to be granted to every users, regardless their account configuration
|
# If you want the client to be granted to every users, regardless their account configuration
|
||||||
granted_to_all_users: true
|
granted_to_all_users: true
|
||||||
|
# If you want users to have performed recent second factor authentication before accessing this client, set this setting to true
|
||||||
|
enforce_mfa_auth: true
|
||||||
```
|
```
|
||||||
|
|
||||||
On the first run, BasicOIDC will create a new administrator with credentials `admin` / `admin`. On first login you will have to change these default credentials.
|
On the first run, BasicOIDC will create a new administrator with credentials `admin` / `admin`. On first login you will have to change these default credentials.
|
||||||
@ -32,7 +34,7 @@ In order to run BasicOIDC for development, you will need to create a least an em
|
|||||||
* [x] `authorization_code` flow
|
* [x] `authorization_code` flow
|
||||||
* [x] Client authentication using secrets
|
* [x] Client authentication using secrets
|
||||||
* [x] Bruteforce protection
|
* [x] Bruteforce protection
|
||||||
* [x] 2 factor authentication
|
* [x] 2 factors authentication
|
||||||
* [x] TOTP (authenticator app)
|
* [x] TOTP (authenticator app)
|
||||||
* [x] Using a security key (Webauthn)
|
* [x] Using a security key (Webauthn)
|
||||||
* [ ] Fully responsive webui
|
* [ ] Fully responsive webui
|
||||||
|
@ -13,7 +13,7 @@ use crate::actors::openid_sessions_actor::{OpenIDSessionsActor, Session, Session
|
|||||||
use crate::actors::users_actor::UsersActor;
|
use crate::actors::users_actor::UsersActor;
|
||||||
use crate::actors::{openid_sessions_actor, users_actor};
|
use crate::actors::{openid_sessions_actor, users_actor};
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::controllers::base_controller::build_fatal_error_page;
|
use crate::controllers::base_controller::{build_fatal_error_page, redirect_user};
|
||||||
use crate::data::action_logger::{Action, ActionLogger};
|
use crate::data::action_logger::{Action, ActionLogger};
|
||||||
use crate::data::app_config::AppConfig;
|
use crate::data::app_config::AppConfig;
|
||||||
use crate::data::client::{ClientID, ClientManager};
|
use crate::data::client::{ClientID, ClientManager};
|
||||||
@ -21,6 +21,7 @@ use crate::data::code_challenge::CodeChallenge;
|
|||||||
use crate::data::current_user::CurrentUser;
|
use crate::data::current_user::CurrentUser;
|
||||||
use crate::data::id_token::IdToken;
|
use crate::data::id_token::IdToken;
|
||||||
use crate::data::jwt_signer::{JWTSigner, JsonWebKey};
|
use crate::data::jwt_signer::{JWTSigner, JsonWebKey};
|
||||||
|
use crate::data::login_redirect::{get_2fa_url, LoginRedirect};
|
||||||
|
|
||||||
use crate::data::session_identity::SessionIdentity;
|
use crate::data::session_identity::SessionIdentity;
|
||||||
use crate::data::user::User;
|
use crate::data::user::User;
|
||||||
@ -128,6 +129,7 @@ fn error_redirect(query: &AuthorizeQuery, error: &str, description: &str) -> Htt
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn authorize(
|
pub async fn authorize(
|
||||||
|
req: HttpRequest,
|
||||||
user: CurrentUser,
|
user: CurrentUser,
|
||||||
id: Identity,
|
id: Identity,
|
||||||
query: web::Query<AuthorizeQuery>,
|
query: web::Query<AuthorizeQuery>,
|
||||||
@ -142,6 +144,12 @@ pub async fn authorize(
|
|||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check if 2FA is required
|
||||||
|
if client.enforce_2fa_auth && user.should_request_2fa_for_critical_functions() {
|
||||||
|
let uri = get_2fa_url(&LoginRedirect::from_req(&req), true);
|
||||||
|
return redirect_user(&uri);
|
||||||
|
}
|
||||||
|
|
||||||
let redirect_uri = query.redirect_uri.trim().to_string();
|
let redirect_uri = query.redirect_uri.trim().to_string();
|
||||||
if !redirect_uri.starts_with(&client.redirect_uri) {
|
if !redirect_uri.starts_with(&client.redirect_uri) {
|
||||||
return HttpResponse::BadRequest().body(build_fatal_error_page("Redirect URI is invalid!"));
|
return HttpResponse::BadRequest().body(build_fatal_error_page("Redirect URI is invalid!"));
|
||||||
|
@ -28,6 +28,10 @@ pub struct Client {
|
|||||||
/// Specify whether a client is granted to all users
|
/// Specify whether a client is granted to all users
|
||||||
#[serde(default = "bool::default")]
|
#[serde(default = "bool::default")]
|
||||||
pub granted_to_all_users: bool,
|
pub granted_to_all_users: bool,
|
||||||
|
|
||||||
|
/// Specify whether recent Second Factor Authentication is required to access this client
|
||||||
|
#[serde(default = "bool::default")]
|
||||||
|
pub enforce_2fa_auth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Client {
|
impl PartialEq for Client {
|
||||||
|
@ -20,10 +20,10 @@ impl FromRequest for CriticalRoute {
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to extract user identity!");
|
.expect("Failed to extract user identity!");
|
||||||
|
|
||||||
if current_user.should_request_2fa_for_critical_function() {
|
if current_user.should_request_2fa_for_critical_functions() {
|
||||||
let url = get_2fa_url(&LoginRedirect::from_req(&req), true);
|
let uri = get_2fa_url(&LoginRedirect::from_req(&req), true);
|
||||||
|
|
||||||
return Err(FromRequestRedirect::new(url));
|
return Err(FromRequestRedirect::new(uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self)
|
Ok(Self)
|
||||||
|
@ -22,7 +22,7 @@ pub struct CurrentUser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CurrentUser {
|
impl CurrentUser {
|
||||||
pub fn should_request_2fa_for_critical_function(&self) -> bool {
|
pub fn should_request_2fa_for_critical_functions(&self) -> bool {
|
||||||
self.user.has_two_factor()
|
self.user.has_two_factor()
|
||||||
&& self
|
&& self
|
||||||
.last_2fa_auth
|
.last_2fa_auth
|
||||||
|
Loading…
Reference in New Issue
Block a user