Chat
Ask me anything
Ithy Logo

Keycloak Integration with .NET 8 Web API and Swagger

Comprehensive Guide to Securing Your Web API with Keycloak Authentication

Keycloak server console with web API code

Highlights

  • Setup and Configuration: Establish Keycloak with a realm, client, and typical user settings, ensuring compatibility with OAuth2 flows.
  • .NET Integration: Employ NuGet packages and proper configuration in Program.cs to integrate JWT Bearer authentication with Swagger’s security definitions.
  • Swagger UI Authorization: Configure Swagger to use OAuth2 flows so that API endpoints can be tested after redirecting to the Keycloak login.

Introduction and Overview

In modern applications, securing your API endpoints becomes crucial. Leveraging Keycloak, an open source identity and access management solution, you can efficiently secure a .NET 8 Web API. When integrated with Swagger—a tool for API documentation and testing—you can enable interactive API exploration while ensuring authorization using Keycloak.

This guide presents an in-depth walkthrough on how to integrate Keycloak with a .NET 8 Web API project, configure Swagger for proper OAuth2-based authentication, and effectively secure endpoints using JWT Bearer tokens. By following this comprehensive approach, you can facilitate both robust security practices and an interactive testing environment for your API consumers.


Setting Up Keycloak

1. Keycloak Server Installation and Configuration

The first step is to have a functioning Keycloak server. You can run Keycloak using Docker for convenience. For instance, using Docker, you can start Keycloak with the following command:


    # Run Keycloak in Docker
    docker run -p 8080:8080 \
      -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
      -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
      quay.io/keycloak/keycloak:26.1.1 start-dev
  

Once running, access the Keycloak Admin Console by navigating to http://localhost:8080/admin and log in with the credentials provided (e.g., admin/admin).

Creating a Realm and Client

A realm in Keycloak acts as a namespace for related configurations. Create a new realm (for example, "MyRealm") and then define a client. The client represents your .NET 8 Web API application.

  • Create a new realm by selecting “Add realm” in the Keycloak console.
  • Once the realm is created, navigate to the “Clients” section and click “Create client”.
  • Assign a unique Client ID (e.g., "my-web-api") and select the OpenID Connect protocol.
  • Configure the client’s access type (e.g., set it to “confidential” if a client secret is needed) and enable the required flows such as the standard or Authorization Code flow.
  • Define valid redirect URIs to include the URL Swagger will use to handle login callbacks. For example, if your API runs on localhost with port 5000, configure the redirect URI to http://localhost:5000/swagger/oauth2-redirect.html.

Make sure to note the Client ID and Client Secret since these will be used later in your .NET configuration.


Integrating Keycloak with a .NET 8 Web API

2. Installing and Configuring NuGet Packages

To integrate Keycloak authentication into your .NET 8 Web API project, you must install several NuGet packages. These packages include support for JWT Bearer tokens, OpenID Connect, and Swagger for interactive API documentation.

Run the following commands in your terminal:


    dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
    dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
    dotnet add package Swashbuckle.AspNetCore
  

These packages set up the fundamental infrastructure to enable secure communication between your API, Swagger, and Keycloak.

Configuring appsettings.json

It’s a good practice to configure your Keycloak parameters in an appsettings.json file. This centralizes configuration and eases maintenance. Here is an example configuration:


{
  "Keycloak": {
    "realm": "MyRealm",
    "auth-server-url": "http://localhost:8080/",
    "ssl-required": "none",
    "resource": "my-web-api",
    "credentials": {
      "secret": "your-client-secret"
    }
  }
}
  

Replace "MyRealm", "my-web-api", and "your-client-secret" with your actual realm name, client ID, and client secret from Keycloak.


Configuring the .NET 8 Web API

3. Setting Up Authentication and Authorization in Program.cs

The heart of the integration lies in your Program.cs file where authentication services are registered, JWT Bearer options are specified, and Swagger is configured to support OAuth2 flows. Below is a detailed example configuration:


    // Necessary namespaces
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.IdentityModel.Tokens;
    using Microsoft.OpenApi.Models;
    
    var builder = WebApplication.CreateBuilder(args);
    
    // Load Keycloak configuration from appsettings.json
    var keycloakConfig = builder.Configuration.GetSection("Keycloak");
    
    // Configure JWT Bearer Authentication using Keycloak settings
    builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        // Authority is Keycloak's url plus realm
        options.Authority = $"{keycloakConfig["auth-server-url"]}realms/{keycloakConfig["realm"]}";
        options.Audience = keycloakConfig["resource"];
        options.RequireHttpsMetadata = false; // Change to true in production
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true
        };
    });
    
    // Add Authorization support
    builder.Services.AddAuthorization();
    
    // Registering Swagger services with OAuth2 support
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(options =>
    {
        // Define API information
        options.SwaggerDoc("v1", new OpenApiInfo
        {
            Title = "My Web API",
            Version = "v1"
        });
    
        // Define the OAuth2.0 scheme that's in use (implicit flow)
        options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = new Uri($"{keycloakConfig["auth-server-url"]}realms/{keycloakConfig["realm"]}/protocol/openid-connect/auth"),
                    TokenUrl = new Uri($"{keycloakConfig["auth-server-url"]}realms/{keycloakConfig["realm"]}/protocol/openid-connect/token"),
                    Scopes = new Dictionary<string, string>
                    {
                        { "openid", "OpenID Connect scope" },
                        { "profile", "Profile information" },
                        { "email", "Email address" }
                    }
                }
            }
        });
    
        // Enforce security requirements globally
        options.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "oauth2"
                    }
                },
                new[] { "openid", "profile", "email" }
            }
        });
    });
    
    var app = builder.Build();
    
    // Configure middleware pipeline
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "My Web API V1");
            // Configure Swagger UI to use OAuth2 authentication
            options.OAuthClientId(keycloakConfig["resource"]);
            options.OAuthClientSecret(keycloakConfig["credentials:secret"]);
            options.OAuthUsePkce(); // Recommended for enhanced security
        });
    }
    
    // Enable HTTPS redirection and authentication middleware
    app.UseHttpsRedirection();
    app.UseAuthentication();
    app.UseAuthorization();
    
    // Sample API endpoint that is secured
    app.MapGet("/protected", () => "Hello, authenticated user!")
       .RequireAuthorization();
    
    app.MapControllers();
    
    app.Run();
  

The above configuration uses JWT Bearer authentication that pulls its authority URL from Keycloak. The Swagger UI is also set up using OAuth2 Security Definitions to interact seamlessly with Keycloak, which ensures that developers and testers can authenticate via the Swagger interface.


Securing API Endpoints

4. Authorization and Endpoint Protection

Once the authentication mechanism is in place, the next critical step is securing your API endpoints using the [Authorize] attribute. This attribute restricts access to endpoints only to authenticated users.

For example, consider the following controller implementation:


    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    
    [ApiController]
    [Route("api/[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        // This action is secured, requiring authentication and authorization
        [HttpGet]
        [Authorize]
        public IActionResult GetForecast()
        {
            return Ok(new
            {
                Message = "This is a protected weather forecast endpoint."
            });
        }
    }
  

This simple example illustrates how you protect your endpoints. You can also implement role-based authorization or policy-based checks if your application demands finer control over access.

Advanced Authorization Techniques

In more demanding scenarios, you may wish to restrict endpoints based on user roles. Keycloak includes roles in the JWT, which you can extract via the realm_access claim. In .NET, you can create authorization policies that examine these roles:


    builder.Services.AddAuthorization(options =>
    {
        options.AddPolicy("AdminOnly", policy =>
            policy.RequireClaim("realm_access", "admin"));
    });
    
    // Usage within a controller action
    [Authorize(Policy = "AdminOnly")]
    public IActionResult GetAdminData()
    {
        return Ok("Welcome admin!");
    }
  

Swagger UI and OAuth2 Integration

5. Configuring Swagger for OAuth2

An essential aspect of this integration is ensuring that the Swagger UI facilitates interactive authentication. Once properly configured, users can click the “Authorize” button within Swagger to initiate the OAuth2 flow via Keycloak.

In the Swagger setup code in Program.cs, you set the OAuthClientId and related fields. This configuration instructs Swagger to direct authentication requests to Keycloak. The steps are:

  • Define the security definition in Swagger with the OAuth2 flow using the Keycloak authorization and token endpoints.
  • Add security requirements to ensure that authenticated calls include a valid token.
  • Configure SwaggerUI so that when the “Authorize” button is pressed, it uses the specified OAuth2 parameters, including PKCE for security (where applicable).

This means that on clicking “Authorize” in the Swagger UI, you are redirected to Keycloak to log in. Once authentication is successful, Swagger receives a token and makes authenticated requests on behalf of the user.


Integrating Keycloak Details into .NET

6. Detailed Table of Configuration Options

Below is a table summarizing important Keycloak configuration settings and their roles in a .NET project:

Configuration Parameter Description Example Value
realm Namespace for Keycloak configurations MyRealm
auth-server-url Base URL for the Keycloak server http://localhost:8080/
resource Client ID used for the application my-web-api
credentials.secret Client secret for confidential access your-client-secret
Valid Redirect URIs Allowed callbacks for OAuth2 authentication http://localhost:5000/swagger/oauth2-redirect.html

This table serves as a quick reference guide when configuring both Keycloak and your .NET 8 Web API.


Testing the Integration

7. Running and Testing the Application

After setting up Keycloak and successfully configuring your .NET 8 Web API with Swagger, the final step is testing the integration. The process involves:

  • Running your .NET application (typically using dotnet run).
  • Navigating to Swagger UI (e.g., http://localhost:5000/swagger).
  • Clicking on the “Authorize” button, which redirects you to the Keycloak login page.
  • Entering valid credentials registered in Keycloak and allowing the OAuth2 flow to complete.
  • Verifying that protected endpoints (ones decorated with the [Authorize] attribute) are not accessible unless a valid token is provided.

Once everything is working as expected, your application is now secured, and Swagger enables you to test authenticated calls seamlessly.


Conclusion and Final Thoughts

In conclusion, integrating Keycloak into a .NET 8 Web API provides a robust security framework utilizing industry-standard OAuth2 flows. This guide has walked through the installation and configuration of Keycloak, its integration with .NET through essential NuGet packages, and the detailed setup of authentication in Program.cs. Additionally, Swagger UI has been configured for OAuth2, allowing interactive testing and API exploration with secure endpoints.

The key benefits of this approach are clear: a centralized identity management system, a secure mechanism to handle authentication via JWT Bearer tokens, and a streamlined developer experience. Furthermore, by utilizing a well-defined authorization strategy (such as role-based policies), you can enhance security by limiting access to sensitive endpoints. These techniques not only safeguard the API but also simplify the testing process, making it easier to validate both the security logic and the API functionality.

As you deploy and scale such an application, remember to enforce additional security best practices like HTTPS in production and continuously monitor authentication flows. Advanced logging and error handling can further bolster your application’s resilience.


References


Recommended Queries for Deeper Insights


Last updated February 21, 2025
Ask Ithy AI
Download Article
Delete Article