Skip to content

Instantly share code, notes, and snippets.

@idusortus
Created August 11, 2025 19:20
Show Gist options
  • Save idusortus/7f40c455948263437f27ecbfd479ccaa to your computer and use it in GitHub Desktop.
Save idusortus/7f40c455948263437f27ecbfd479ccaa to your computer and use it in GitHub Desktop.

Keycloak + .NET 9 AuthZ Integration Reference

Quick reference for integrating Keycloak 26.2 realm roles, groups, users, and claims with .NET 9 and Blazor WASM applications.
Includes best practices, concrete examples, and step-by-step Keycloak UI instructions.


1. Concepts: Users, Groups, Roles, Claims

  • Users: Individual accounts for authentication.
  • Groups: Collections of users for bulk role/permission assignment.
  • Roles: Permissions/access levels. Prefer realm roles for API and SPA authZ.
  • Claims: Key-value pairs in JWT tokens, used by .NET/Blazor for authorization.

2. Recommended Patterns

  • Assign roles to groups, then add users to groups for scalable management.
  • Use realm roles for API and SPA authZ.
  • Map roles and custom attributes to JWT claims.

3. Assigning Roles via Groups

  1. Create realm roles: SystemAdmin, Admin, PaidUser, etc.
  2. Create groups: SystemAdmins, Admins, etc.
  3. Assign roles to groups:
    Groups → Select group → Role Mappings → Assign realm roles
  4. Add users to groups:
    Users → Select user → Groups → Join group

4. Add Custom Attribute to Role

  1. Roles → Select realm role (e.g., SystemAdmin)
  2. Attributes tab: Add attribute (e.g., CanCreateWhirledPeas: true)
  3. Map this with a protocol mapper for custom claim exposure.

5. Map Realm Roles to Top-Level JWT Claim for .NET

Purpose:

Enable [Authorize(Roles="...")] and .RequireRole(...) in .NET 9.

Step-by-Step: Add Mapper for Realm Roles

  1. Clients → Select your client (wiscodev-api or wiscodev-spa)
  2. Client Scopes tab → Find/select <client>-dedicated (e.g., wiscodev-api-dedicated)
  3. Click on <client>-dedicated to edit
  4. Mappers tab → Add Mapper
  5. Choose "By configuration"
  6. Mapper Settings:
    • Mapper Type: User Realm Role
    • Name: role
    • Token Claim Name: role
    • Claim JSON Type: String
    • Add to ID token: ON (for SPA)
    • Add to Access token: ON (for API)
    • Multivalued: ON
  7. Save

Repeat for all relevant clients (API, SPA, etc).


6. JWT Example After Mapping

"role": [
  "SystemAdmin",
  "Admin",
  "PaidUser",
  "Guest"
]

7. .NET 9 Usage

// Protect endpoint by role
app.MapGet("/admin/data", () => Results.Ok("Only SystemAdmins can see this!"))
   .RequireAuthorization(policy => policy.RequireRole("SystemAdmin"));

// Or use attribute
[Authorize(Roles = "SystemAdmin")]
public IActionResult AdminPage() { ... }

8. Custom Claims for Attribute-Based Policies

  • Add attribute to role or user in Keycloak.
  • Map with a User Attribute protocol mapper.
  • Use .RequireClaim("CanCreateWhirledPeas", "true") in .NET.

9. Summary Table

Concept Keycloak UI Path .NET Usage Example Value in JWT
User Users → Create/Edit - -
Group Groups → Add/Edit, Add Users - -
Role Roles → Add/Edit, Assign to Groups [Authorize(Roles=...)] "role": ["SystemAdmin", ...]
Attribute Roles/User → Attributes .RequireClaim("...") "CanCreateWhirledPeas": true
Role Mapper Client Scopes → dedicated → Mappers [Authorize(Roles=...)] "role": ["SystemAdmin", ...]

TL;DR

  • Use realm roles for scalable, cross-client authorization.
  • Assign roles to groups, add users to groups.
  • Map realm roles to a top-level role claim (multivalued) via a User Realm Role mapper in the client scope.
  • .NET’s standard role-based auth works out of the box.
  • For custom claims, use User Attribute mappers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment