Add oidc-provider-mock dev setup with docker-compose and dotenvy
- docker-compose.yml runs oidc-provider-mock on :9400 with predefined alice/bob users carrying preferred_username claims - .env auto-loaded via dotenvy for zero-config local dev - index route now redirects unauthenticated users to the login flow instead of returning 401
This commit is contained in:
+7
-4
@@ -1,9 +1,12 @@
|
|||||||
# Base URL of the OIDC provider (e.g. Keycloak realm URL)
|
# Base URL of the OIDC provider.
|
||||||
OIDC_PROVIDER_URL=http://localhost:8080
|
# For local development, `docker-compose up -d` starts oidc-provider-mock
|
||||||
|
# at http://localhost:9400 (accepts any client ID/secret).
|
||||||
|
# For Keycloak use e.g. https://keycloak.example.com/realms/myrealm
|
||||||
|
OIDC_PROVIDER_URL=http://localhost:9400
|
||||||
|
|
||||||
# OAuth2 client credentials (required)
|
# OAuth2 client credentials (required)
|
||||||
OIDC_CLIENT_ID=your-client-id
|
OIDC_CLIENT_ID=dev-client
|
||||||
OIDC_CLIENT_SECRET=your-client-secret
|
OIDC_CLIENT_SECRET=dev-secret
|
||||||
|
|
||||||
# Full callback URL — must match the redirect URI configured at the provider
|
# Full callback URL — must match the redirect URI configured at the provider
|
||||||
OIDC_REDIRECT_URI=http://localhost:3000/auth/callback
|
OIDC_REDIRECT_URI=http://localhost:3000/auth/callback
|
||||||
|
|||||||
Generated
+1
@@ -216,6 +216,7 @@ dependencies = [
|
|||||||
"axum",
|
"axum",
|
||||||
"axum-oidc-client",
|
"axum-oidc-client",
|
||||||
"base64",
|
"base64",
|
||||||
|
"dotenvy",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
dotenvy = "0.15"
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
oidc:
|
||||||
|
image: ghcr.io/geigerzaehler/oidc-provider-mock:latest
|
||||||
|
ports:
|
||||||
|
- "9400:9400"
|
||||||
|
command:
|
||||||
|
- --user-claims
|
||||||
|
- '{"sub": "alice", "preferred_username": "alice", "email": "alice@example.com", "name": "Alice"}'
|
||||||
|
- --user-claims
|
||||||
|
- '{"sub": "bob", "preferred_username": "bob", "email": "bob@example.com", "name": "Bob"}'
|
||||||
+24
-4
@@ -1,13 +1,20 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::{http::StatusCode, response::Html, routing::get, Json, Router};
|
use axum::{
|
||||||
|
extract::State,
|
||||||
|
http::StatusCode,
|
||||||
|
response::{Html, IntoResponse, Redirect, Response},
|
||||||
|
routing::get,
|
||||||
|
Json, Router,
|
||||||
|
};
|
||||||
use axum_oidc_client::authentication::AuthenticationLayer;
|
use axum_oidc_client::authentication::AuthenticationLayer;
|
||||||
use axum_oidc_client::authentication::builder::OAuthConfigurationBuilder;
|
use axum_oidc_client::authentication::builder::OAuthConfigurationBuilder;
|
||||||
use axum_oidc_client::authentication::logout::handle_default_logout::DefaultLogoutHandler;
|
use axum_oidc_client::authentication::logout::handle_default_logout::DefaultLogoutHandler;
|
||||||
use axum_oidc_client::auth_cache::AuthCache;
|
use axum_oidc_client::auth_cache::AuthCache;
|
||||||
use axum_oidc_client::auth_session::AuthSession;
|
use axum_oidc_client::auth_session::AuthSession;
|
||||||
use axum_oidc_client::cache::{TwoTierAuthCache, config::TwoTierCacheConfig};
|
use axum_oidc_client::cache::{TwoTierAuthCache, config::TwoTierCacheConfig};
|
||||||
|
use axum_oidc_client::extractors::OptionalAuthSession;
|
||||||
use axum_oidc_client::sql_cache::{SqlAuthCache, SqlCacheConfig};
|
use axum_oidc_client::sql_cache::{SqlAuthCache, SqlCacheConfig};
|
||||||
use axum_oidc_client::authentication::CodeChallengeMethod;
|
use axum_oidc_client::authentication::CodeChallengeMethod;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
@@ -78,12 +85,22 @@ async fn hello(session: AuthSession) -> Result<Json<HelloResponse>, StatusCode>
|
|||||||
Ok(Json(HelloResponse { preferred_username }))
|
Ok(Json(HelloResponse { preferred_username }))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn index(_session: AuthSession) -> Html<&'static str> {
|
#[derive(Clone)]
|
||||||
Html(INDEX_HTML)
|
struct AppState {
|
||||||
|
login_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index(session: OptionalAuthSession, State(state): State<AppState>) -> Response {
|
||||||
|
match session.0 {
|
||||||
|
Some(_) => Html(INDEX_HTML).into_response(),
|
||||||
|
None => Redirect::to(&state.login_path).into_response(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
dotenvy::dotenv().ok();
|
||||||
|
|
||||||
let provider_url = env_required("OIDC_PROVIDER_URL");
|
let provider_url = env_required("OIDC_PROVIDER_URL");
|
||||||
let client_id = env_required("OIDC_CLIENT_ID");
|
let client_id = env_required("OIDC_CLIENT_ID");
|
||||||
let client_secret = env_required("OIDC_CLIENT_SECRET");
|
let client_secret = env_required("OIDC_CLIENT_SECRET");
|
||||||
@@ -131,7 +148,10 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Arc::new(config),
|
Arc::new(config),
|
||||||
cache,
|
cache,
|
||||||
logout_handler,
|
logout_handler,
|
||||||
));
|
))
|
||||||
|
.with_state(AppState {
|
||||||
|
login_path: auth_base_path,
|
||||||
|
});
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
|
||||||
println!("Listening on http://0.0.0.0:3000");
|
println!("Listening on http://0.0.0.0:3000");
|
||||||
|
|||||||
Reference in New Issue
Block a user