Skip to content

fenixkitdev/FenixKit-MongoDB-Keycloak

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FenixKit — .NET Minimal API MongoDB + Keycloak Auth

FenixKit

Get it here: fenixkit.dev

Ship faster. Build smarter.
A production-ready .NET Minimal API starter with Keycloak JWT authentication, MongoDB, and zero manual setup.

Keycloak JWT auth is the hardest part to get right in a new .NET API. Wrong token validation, missing role checks, broken Swagger login flows, no health check on the auth server — all fixable, all time-consuming. FenixKit Auth ships with all of it wired up from day one.

Keycloak runs out of the box. A pre-built realm with two test users, a registered client, and role mappings is imported automatically when the Docker stack starts. No Keycloak console setup required.


What's Inside

Feature Details
Keycloak Auth JWT Bearer validation
Role-based policies Authenticated and AdminOnly policies wired in from the start
Swagger OAuth2 PKCE Authorize button in Swagger UI logs in via Keycloak — tokens injected automatically
Pre-built realm realm-export.json imported at startup — two test users, one client, two roles
Keycloak health check /health/ready includes Keycloak reachability via OIDC discovery
Auth example endpoints /api/auth-examples/me and /api/auth-examples/admin — working patterns to copy
Minimal API .NET 8 / .NET 10 — route grouping, no controllers, fast startup
MongoDB MongoRepository via IDBRepository, singleton, health-checked
ErrorOr Result pattern throughout — no exceptions for control flow
Offset + Cursor pagination Both strategies included, pick the right one per endpoint
BaseRepository 7 overridable hooks — extend CRUD without rewriting it
Global error handler RFC 7807 ProblemDetails on every unhandled exception
Docker + Compose API + MongoDB + Keycloak, healthcheck-gated startup order
Environment variables .env.example with placeholder resolution via Steeltoe

Why Not Wire Auth Yourself?

Starting from scratch Using FenixKit Auth
Hours configuring JWT Bearer options Pre-configured, tested, ready
Manual Keycloak realm + client setup realm-export.json imported on first docker compose up
Swagger Authorize button doesn't work OAuth2 PKCE flow wired in — click Authorize, log in, done
Role checks scattered across handlers Centralised policies: RequireAuthorization("AdminOnly")
No health check on the auth server Keycloak OIDC discovery check in /health/ready
Token validation breaks on key rotation Keycloak public keys fetched automatically via metadata URL
Reading claims is inconsistent Typed UserInfoResponse with username, email, roles, subject

Authentication Architecture

Keycloak issues JWT tokens. The API validates every token against the Keycloak — fetched automatically from the OIDC discovery document.

Client → POST /realms/fenixkit/protocol/openid-connect/token → JWT
Client → GET  /api/products/ + Bearer <JWT> → API validates → 200 OK
                                                             → 401 if missing/invalid
                                                             → 403 if wrong role

Protecting Endpoints

// Any authenticated user
group.MapGet("/orders", GetOrders)
    .RequireAuthorization("Authenticated");

// Admin role only
group.MapDelete("/orders/{id}", DeleteOrder)
    .RequireAuthorization("AdminOnly");

Both policies are defined in Auth/Keycloak/Extensions/AuthExtensions.cs. Adding a new policy is one block:

.AddPolicy("PremiumOnly", policy =>
    policy.RequireAuthenticatedUser()
          .RequireRole("premium"))

Then assign the premium realm role to users in the Keycloak admin console.


Reading the Current User

private static IResult Me(HttpContext ctx)
{
    var username = ctx.User.Identity?.Name;           // preferred_username claim
    var email    = ctx.User.FindFirst("email")?.Value;
    var subject  = ctx.User.FindFirst("sub")?.Value;
    var isAdmin  = ctx.User.IsInRole("admin");
    var roles    = ctx.User.FindAll("roles").Select(c => c.Value);

    return Results.Ok(new UserInfoResponse(username, email, subject, roles));
}

/api/auth-examples/me is a working example of this pattern included in the kit.


Pre-configured Keycloak Realm

keycloak/realm-export.json is imported automatically on first startup. No manual steps.

Item Value
Realm fenixkit
Client fenixkit-api (Authorization Code + PKCE)
Redirect URIs http://localhost:8081/* (Swagger UI)
Realm roles admin, user
Test user admin-test / admin123 — roles: admin, user
Test user user-test / user123 — roles: user

To customise the realm, edit keycloak/realm-export.json or use the Keycloak admin console at http://localhost:8082.


Health Checks

GET /health/live   → Liveness  — is the process alive?
GET /health/ready  → Readiness — is MongoDB reachable? Is Keycloak reachable?

The Keycloak check fetches the OIDC discovery document (/.well-known/openid-configuration). A non-2xx response returns Degraded; a network error returns Unhealthy.

{
  "status": "Healthy",
  "entries": {
    "mongodb":  { "status": "Healthy" },
    "keycloak": { "status": "Healthy" }
  }
}

Quick Start

# 1. Copy the environment file
cp .env.example .env

# 2. Start the full stack — API + MongoDB + Keycloak
docker compose up --build

# API    → http://localhost:8081
# Swagger → http://localhost:8081/swagger
# Keycloak admin → http://localhost:8082  (admin / changeme)

Open Swagger, click Authorize, log in as admin-test / admin123. All requests will carry the Bearer token automatically.


Error Responses

All errors — including auth errors — follow RFC 7807 application/problem+json:

Status Title Cause
401 Auth.Unauthorized Missing, expired, or invalid JWT
403 Auth.Forbidden Valid JWT but insufficient role
404 Resource.NotFound Entity not found
409 Resource.Conflict Duplicate detected
422 Validation Error Input validation failed
500 Server Error Unhandled exception — ProblemDetails, never HTML

Technologies

Package Role
.NET 8 LTS (C# 12) · .NET 10 (C# 14) Runtime and language
Keycloak 24 OIDC / OAuth2 identity provider
Microsoft.AspNetCore.Authentication.JwtBearer JWT Bearer validation
MongoDB.Driver Official MongoDB .NET driver
ErrorOr v2 Result pattern — no exceptions for domain errors
Swashbuckle.AspNetCore Swagger UI + OAuth2 PKCE flow
DotNetEnv + Steeltoe .env file + ${VAR} placeholder resolution in appsettings
Docker + Docker Compose Full stack in one command

Upgrading from FenixKit Base

Already own the base kit? See MIGRATION.md — step-by-step instructions for adding Keycloak auth to an existing FenixKit project or any .NET 8 Minimal API.


License

FenixKit Auth is a commercial product. Each purchase grants a lifetime licence for unlimited personal and commercial projects.

👉 fenixkit.dev

About

.Net 8 Minimal API Starter Kit with MongoDB + Keycloak

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors