loco_keycloak_auth/
lib.rs1pub mod initializer;
2pub mod settings;
3
4pub use axum_keycloak_auth::decode::KeycloakToken;
5use axum_keycloak_auth::{
6 Url,
7 instance::{KeycloakAuthInstance, KeycloakConfig},
8 layer::KeycloakAuthLayer,
9};
10use loco_rs::prelude::*;
11use settings::{KeycloakSettings, Settings};
12
13pub struct Keycloak {
22 pub layer: KeycloakAuthLayer<String>,
23}
24
25impl Keycloak {
26 pub fn from_context(ctx: &AppContext) -> Result<Self> {
27 build_keycloak_layer(ctx).map(|layer| Keycloak { layer })
28 }
29}
30
31pub fn build_keycloak_layer(ctx: &AppContext) -> Result<KeycloakAuthLayer<String>> {
34 let full_settings: Settings = serde_json::from_value(
35 ctx.config
36 .settings
37 .clone()
38 .ok_or_else(|| Error::Message("Missing `settings` in config".into()))?,
39 )
40 .map_err(|err| Error::Message(format!("Invalid settings: {}", err)))?;
41
42 let settings: KeycloakSettings = full_settings.keycloak_settings;
43
44 let instance =
45 KeycloakAuthInstance::new(
46 KeycloakConfig::builder()
47 .server(Url::parse(&settings.url).map_err(|err| {
48 Error::Message(format!("Invalid Keycloak server URL: {}", err))
49 })?)
50 .realm(settings.realm)
51 .build(),
52 );
53
54 Ok(KeycloakAuthLayer::<String>::builder()
55 .instance(instance)
56 .passthrough_mode(settings.passthrough_mode.0)
57 .persist_raw_claims(settings.persist_raw_claims)
58 .expected_audiences(settings.expected_audiences)
59 .build())
60}