Appearance
Authentication & Authorization Overview
Section: 14 — Auth
Last Updated: 2026-05-30
Scope: Keycloak, JWT, dual-token, session limiting, multi-realm
Architecture at a Glance
Microtec ERP uses Keycloak as the central Identity Provider (IdP) with a custom dual-token design to bridge standard OIDC with ERP-specific business concepts.
Key Components
| Component | Technology | Purpose |
|---|---|---|
| Identity Provider | Keycloak 24.x | OIDC / OAuth 2.0 authentication |
| ERP Token Service | .NET 8 (Auth project) | Business-context token generation |
| Session Store | Azure Redis | Session limiting + token blacklist |
| API Gateway | Ocelot + YARP | Token validation + routing |
| Custom SPIs | Keycloak SPI (Java) | Multi-account, claim mapping |
Dual-Token Design
See dual-token-design.md for the complete design doc.
The core insight: Keycloak knows who you are; ERP knows what you can access.
| Token | Issued By | Contains | Lifetime |
|---|---|---|---|
| Keycloak JWT | Keycloak IdP | User identity, email, roles | 5–15 min |
| ERP Access Context Token | ERP Auth Service | Company, Branch, Module permissions | 1 hour |
Both tokens are required for every API request:
Authorization: Bearer <keycloak-jwt>— identity verificationX-Access-Context: <erp-token>— business context
Realms
ERP uses two Keycloak realms to separate concerns:
| Realm | Applications | Users | Custom SPIs |
|---|---|---|---|
microtec | All ERP apps (Angular + mobile) | Tenant employees | company-branch-mapper, erp-policy-mapper |
businessowner | BO portal (admin) | Tenant admins, resellers | Simplified — no company-branch mapping |
Realm Isolation
Realm isolation means:
- Session tokens from
microtecare not valid inbusinessownerand vice versa - Each realm has its own token signing keys
- Admin users in
businessownercannot access ERP tenant data
Custom Keycloak SPIs
Three custom SPIs are deployed in the KeycloakProviders/ directory:
| SPI | Purpose | Realm |
|---|---|---|
company-branch-mapper | Maps selected company/branch to JWT claims | microtec |
erp-policy-mapper | Maps ERP module permissions to JWT claims | microtec |
multi-account-switcher | Allows switching between companies without re-login | microtec |
See Keycloak section — 06 for SPI deployment and configuration.
Session Limiting
See session-limiting.md for full configuration.
- Default: 1 active session per user (globally)
- Backend: Redis-backed session registry
- Eviction policy: Oldest session evicted when limit reached
- Config key:
SessionValidation:GlobalDefaultMaxSessions
JWT Claims Reference
See jwt-claims.md for the complete claim mapping table.
Key custom claims added by Keycloak SPIs:
json
{
"sub": "user-uuid",
"tenant": "acme-corp",
"companyid": "550e8400-...",
"branchId": "...",
"erp_policies": "accounting:read,hr:write,inventory:read",
"erp_id": "...",
"subdomain": "acme"
}Authentication Flow
Service Registration
Backend services register auth via the Microtec.Web.Core NuGet package:
csharp
// Program.cs (all microservices)
builder.Services
.AddMicrotecAuthentication(builder.Configuration)
.AddMicrotecAuthorization();Configuration required:
json
{
"Keycloak": {
"Authority": "https://auth.microtec-test.com/realms/microtec",
"Audience": "erp-api",
"ValidateIssuer": true,
"ValidateAudience": true
}
}Security Considerations
| Risk | Mitigation |
|---|---|
| Token theft | Short-lived Keycloak JWTs (5–15 min) |
| Session hijacking | Redis session binding + IP validation (optional) |
| Multi-session abuse | Session limiting (1 session/user) |
| Cross-tenant access | TenantId in JWT + global EF Core query filter |
| Privilege escalation | ERP policy mapper validates against DB permissions |