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)
|
||||
OIDC_PROVIDER_URL=http://localhost:8080
|
||||
# Base URL of the OIDC provider.
|
||||
# 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)
|
||||
OIDC_CLIENT_ID=your-client-id
|
||||
OIDC_CLIENT_SECRET=your-client-secret
|
||||
OIDC_CLIENT_ID=dev-client
|
||||
OIDC_CLIENT_SECRET=dev-secret
|
||||
|
||||
# Full callback URL — must match the redirect URI configured at the provider
|
||||
OIDC_REDIRECT_URI=http://localhost:3000/auth/callback
|
||||
|
||||
Generated
+1
@@ -216,6 +216,7 @@ dependencies = [
|
||||
"axum",
|
||||
"axum-oidc-client",
|
||||
"base64",
|
||||
"dotenvy",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
|
||||
@@ -11,3 +11,4 @@ serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
base64 = "0.22"
|
||||
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::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::builder::OAuthConfigurationBuilder;
|
||||
use axum_oidc_client::authentication::logout::handle_default_logout::DefaultLogoutHandler;
|
||||
use axum_oidc_client::auth_cache::AuthCache;
|
||||
use axum_oidc_client::auth_session::AuthSession;
|
||||
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::authentication::CodeChallengeMethod;
|
||||
use base64::Engine;
|
||||
@@ -78,12 +85,22 @@ async fn hello(session: AuthSession) -> Result<Json<HelloResponse>, StatusCode>
|
||||
Ok(Json(HelloResponse { preferred_username }))
|
||||
}
|
||||
|
||||
async fn index(_session: AuthSession) -> Html<&'static str> {
|
||||
Html(INDEX_HTML)
|
||||
#[derive(Clone)]
|
||||
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]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
dotenvy::dotenv().ok();
|
||||
|
||||
let provider_url = env_required("OIDC_PROVIDER_URL");
|
||||
let client_id = env_required("OIDC_CLIENT_ID");
|
||||
let client_secret = env_required("OIDC_CLIENT_SECRET");
|
||||
@@ -131,7 +148,10 @@ async fn main() -> anyhow::Result<()> {
|
||||
Arc::new(config),
|
||||
cache,
|
||||
logout_handler,
|
||||
));
|
||||
))
|
||||
.with_state(AppState {
|
||||
login_path: auth_base_path,
|
||||
});
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
|
||||
println!("Listening on http://0.0.0.0:3000");
|
||||
|
||||
Reference in New Issue
Block a user