Implemented authentication with Keycloak

This commit is contained in:
Dennis Nemec
2025-10-02 20:22:11 +02:00
parent e8954ba5c1
commit b87d7e0268
15 changed files with 1697 additions and 94 deletions

View File

@ -1,18 +1,22 @@
use crate::api::{handle_login, handle_post};
use crate::api::handle_post;
use crate::config::load_config;
use crate::middleware::AppState;
use crate::repository::RedisRepository;
use crate::util::initialize_logging;
use axum::routing::post;
use axum::{Extension, Router};
use axum_keycloak_auth::instance::{KeycloakAuthInstance, KeycloakConfig};
use axum_keycloak_auth::layer::KeycloakAuthLayer;
use axum_keycloak_auth::{PassthroughMode, Url};
use log::info;
use std::sync::Arc;
mod api;
mod auth;
mod config;
mod gsd;
mod middleware;
mod repository;
mod service_gsd;
mod util;
#[tokio::main]
@ -26,27 +30,53 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let redis_url = config.redis_url.clone();
let host_url = config.get_host_url().clone();
info!("Initializing redis server");
let state = Arc::new(AppState {
config: config.clone(),
repository: RedisRepository::try_new(redis_url).await?,
gsd_service: (&config).into(),
oauth_client: auth::create_oauth_client(&config),
frontend_url: config.frontend_url.clone(),
});
let app = Router::new()
.route("/login", post(handle_login))
info!("Starting axum server");
let keycloak_instance: Arc<KeycloakAuthInstance> = Arc::new(KeycloakAuthInstance::new(
KeycloakConfig::builder()
.server(Url::parse("http://localhost:8080/").unwrap())
.realm(String::from("master"))
.build(),
));
let auth_router = auth::router(state.clone());
let proxy_router = Router::new()
.route("/{*wildcard}", post(handle_post))
.layer(Extension(state.clone()))
.route_layer(Extension(state.clone()))
.route_layer(axum::middleware::from_fn_with_state(
state.clone(),
middleware::gsd_add_header,
middleware::gsd_decorate_header,
))
.route_layer(
KeycloakAuthLayer::<String>::builder()
.instance(keycloak_instance.clone())
.passthrough_mode(PassthroughMode::Block)
.persist_raw_claims(false)
.expected_audiences(vec![String::from("account")])
//.required_roles(vec![])
.build(),
)
.route_layer(axum::middleware::from_fn_with_state(
state.clone(),
middleware::auth_middleware,
middleware::session_auth_middleware,
))
.with_state(state);
let listener = tokio::net::TcpListener::bind(host_url).await.unwrap();
let app = Router::new().merge(proxy_router).merge(auth_router);
info!("Listening on {}", host_url);
let listener = tokio::net::TcpListener::bind(host_url.clone())
.await
.unwrap();
axum::serve(listener, app).await.unwrap();