DEV Community

Siddharth Bhamare
Siddharth Bhamare

Posted on

Day 4 - πŸ” Securing API with Keycloak

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
Enter fullscreen mode Exit fullscreen mode

Access the admin console: http://localhost:8080

  • Username: admin
  • Password: admin

Keycloak Configuration

  1. Create a Realm: demo-realm
  2. Create a Client for Your API:
  3. 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
Enter fullscreen mode Exit fullscreen mode

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();

Enter fullscreen mode Exit fullscreen mode

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 πŸ›οΈ");
}

Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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)