Can define additional claims on per-client basis
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-03-31 18:37:08 +02:00
parent d087c5629d
commit 91ef6c25d5
5 changed files with 162 additions and 43 deletions

View File

@ -16,7 +16,7 @@ use crate::constants::*;
use crate::controllers::base_controller::{build_fatal_error_page, redirect_user};
use crate::data::action_logger::{Action, ActionLogger};
use crate::data::app_config::AppConfig;
use crate::data::client::{AuthenticationFlow, ClientID, ClientManager};
use crate::data::client::{AdditionalClaims, AuthenticationFlow, ClientID, ClientManager};
use crate::data::code_challenge::CodeChallenge;
use crate::data::current_user::CurrentUser;
use crate::data::id_token::IdToken;
@ -270,6 +270,7 @@ pub async fn authorize(
auth_time: SessionIdentity(Some(&id)).auth_time(),
nonce: query.nonce.clone(),
email: user.email.clone(),
additional_claims: client.claims_id_token(&user),
};
log::trace!("New OpenID id token: {:#?}", &id_token);
@ -533,7 +534,8 @@ pub async fn token(
issued_at: time(),
auth_time: session.auth_time,
nonce: session.nonce,
email: user.email,
email: user.email.to_string(),
additional_claims: client.claims_id_token(&user),
};
OpenIDTokenResponse {
@ -641,6 +643,7 @@ pub async fn user_info_post(
query: web::Query<UserInfoQuery>,
sessions: web::Data<Addr<OpenIDSessionsActor>>,
users: web::Data<Addr<UsersActor>>,
clients: web::Data<Arc<ClientManager>>,
) -> impl Responder {
user_info(
req,
@ -649,6 +652,7 @@ pub async fn user_info_post(
.or(query.0.access_token),
sessions,
users,
clients,
)
.await
}
@ -658,8 +662,18 @@ pub async fn user_info_get(
query: web::Query<UserInfoQuery>,
sessions: web::Data<Addr<OpenIDSessionsActor>>,
users: web::Data<Addr<UsersActor>>,
clients: web::Data<Arc<ClientManager>>,
) -> impl Responder {
user_info(req, query.0.access_token, sessions, users).await
user_info(req, query.0.access_token, sessions, users, clients).await
}
#[derive(serde::Serialize)]
pub struct UserInfoWithCustomClaims {
#[serde(flatten)]
info: OpenIDUserInfo,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(flatten)]
additional_claims: Option<AdditionalClaims>,
}
/// Authenticate request using RFC6750 <https://datatracker.ietf.org/doc/html/rfc6750>///
@ -668,6 +682,7 @@ async fn user_info(
token: Option<String>,
sessions: web::Data<Addr<OpenIDSessionsActor>>,
users: web::Data<Addr<UsersActor>>,
clients: web::Data<Arc<ClientManager>>,
) -> impl Responder {
let token = match token {
Some(t) => t,
@ -711,6 +726,10 @@ async fn user_info(
return user_info_error("invalid_request", "Access token has expired!");
}
let client = clients
.find_by_id(&session.client)
.expect("Could not extract client information!");
let user: Option<User> = users
.send(users_actor::GetUserRequest(session.user))
.await
@ -723,13 +742,16 @@ async fn user_info(
Some(u) => u,
};
HttpResponse::Ok().json(OpenIDUserInfo {
name: Some(user.full_name()),
sub: user.uid.0,
given_name: Some(user.first_name),
family_name: Some(user.last_name),
preferred_username: Some(user.username),
email: Some(user.email),
email_verified: Some(true),
HttpResponse::Ok().json(UserInfoWithCustomClaims {
info: OpenIDUserInfo {
name: Some(user.full_name()),
sub: user.uid.0.to_string(),
given_name: Some(user.first_name.to_string()),
family_name: Some(user.last_name.to_string()),
preferred_username: Some(user.username.to_string()),
email: Some(user.email.to_string()),
email_verified: Some(true),
},
additional_claims: client.claims_user_info(&user),
})
}