If you already have a .NET API running, you can integrate Keycloak to provide authentication and role-based authorization without rewriting your backend. This guide covers setup, token handling, role-based policies, and common questions.
What is Keycloak?
Keycloak is an open-source identity and access management (IAM) solution. It helps developers secure applications and services with minimal effort. Keycloak provides:
- Single Sign-On (SSO): Users log in once to access multiple apps.
- User Management: Create, update, and delete users via admin console or API.
- Role-Based Access Control (RBAC): Assign roles to users to restrict access to specific resources.
- Support for Multiple Protocols: OpenID Connect, OAuth2, SAML.
- Integration with Multiple Platforms: Works with Java, .NET, Node.js, and more.
- Keycloak removes the need to implement authentication and authorization logic in your application, making it ideal for both development and production environments.
Why Keycloak?
Even if you are using IdentityServer (Duende), Keycloak provides:
- Ready-to-use IAM server with UI and SSO.
- Role management and RBAC to secure endpoints easily.
- Open-source and production-ready with clustering and Kubernetes support.
- Supports multiple protocols for future integrations (mobile, frontend, microservices).
When to choose Keycloak:
- Centralized authentication across multiple services.
- Admin UI to manage users, roles, and clients.
- Plan to implement SSO for frontend apps or mobile apps.
Pull Request Example
- Git Hub Pull Requests demonstrates:
- JWT authentication in an existing API
- Role-based authorization (admin and vendor)
- Minimal changes to existing controllers
Setting Up Keycloak (Docker)
The easiest way to try Keycloak locally is via Docker.
Official Guide: Keycloak Docker Getting Started
docker run -d \
--name keycloak \
-p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:25.0.6 start-dev
Access the admin console: http://localhost:8080
- Username: admin
- Password: admin
Keycloak Configuration
- Create a Realm: demo-realm
- Create a Client for Your API:
- Client ID: demo-api
- Protocol: OpenID Connect
- Access Type: confidential
- Copy the Client Secret
Create Roles:
- admin
- vendor
Create Users and Assign Roles:
- Example: admin-user β assign admin
- Example: vendor-user β assign vendor
Securing Your Existing .NET API
Assuming your API is already created, you only need to add authentication and authorization.
Microsoft.AspNetCore.Authentication.JwtBearer
Update Program.cs
var builder = WebApplication.CreateBuilder(args);
// Authentication
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost:8080/realms/demo-realm";
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateAudience = true,
ValidAudience = "demo-api"
};
});
// Authorization policies
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("admin"));
options.AddPolicy("VendorOnly", policy => policy.RequireRole("vendor"));
options.AddPolicy("AdminOrVendor", policy => policy.RequireRole("admin", "vendor"));
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers(); // Existing API controllers
app.Run();
Applying Role-Based Access in Controllers
[Authorize(Roles = "admin")]
[Route("api/[controller]")]
public class AdminController : ControllerBase
{
[HttpGet("dashboard")]
public IActionResult GetAdminData() => Ok("Hello Admin π");
}
[Authorize(Roles = "vendor")]
[Route("api/[controller]")]
public class VendorController : ControllerBase
{
[HttpGet("dashboard")]
public IActionResult GetVendorData() => Ok("Hello Vendor ποΈ");
}
Getting an Access Token
Using cURL [use powershell] - Update your url, username, password and client id
curl.exe --insecure -X POST "http://localhost:8080/realms/demo-realm/protocol/openid-connect/token" `
>> -H "Content-Type: application/x-www-form-urlencoded" `
>> -d "grant_type=password&client_id=demo-api&client_secret=<client-secret>&username=yourusername&password=yourpassword"
Authority vs ValidIssuer
- Authority: Base URL of Keycloak (http://localhost:8080/realms/demo-realm). Middleware fetches metadata automatically.
- ValidIssuer: Exact iss claim from token. Usually not required unless running behind reverse proxies.
Best Practice: Use Authority + ValidAudience. Only override ValidIssuer if needed.
Common Doubts/Questions
- Why Keycloak over IdentityServer?
Keycloak is ready-to-use with UI, SSO, and role management; IdentityServer requires more custom coding.
- Can multiple APIs share one realm?
Yes, each API can have its own client in Keycloak.
- How are roles assigned?
Realm roles = global, Client roles = API-specific, users can have multiple roles.
- Is Keycloak production-ready?
Yes, supports clustering, load-balancing, and Kubernetes deployment.
- Can I do client-to-client authentication?
Yes, using the client credentials grant type.
Resources:
Keycloak Docker Guide: https://www.keycloak.org/getting-started/getting-started-docker
GitHub PR: SmartKart-Catalog #4 https://github.com/SiddharthBhamare/SmartKart-Catalog/pull/4
Top comments (0)