Keycloak.Net.Sdk
1.2.0
See the version list below for details.
dotnet add package Keycloak.Net.Sdk --version 1.2.0
NuGet\Install-Package Keycloak.Net.Sdk -Version 1.2.0
<PackageReference Include="Keycloak.Net.Sdk" Version="1.2.0" />
<PackageVersion Include="Keycloak.Net.Sdk" Version="1.2.0" />
<PackageReference Include="Keycloak.Net.Sdk" />
paket add Keycloak.Net.Sdk --version 1.2.0
#r "nuget: Keycloak.Net.Sdk, 1.2.0"
#:package Keycloak.Net.Sdk@1.2.0
#addin nuget:?package=Keycloak.Net.Sdk&version=1.2.0
#tool nuget:?package=Keycloak.Net.Sdk&version=1.2.0
Keycloak.Net.Sdk
A modular .NET 8 SDK for integrating with Keycloak using IHttpClientFactory, typed services, and built-in retry policies.
Features
- Sign up / sign in users
- Manage users (get, enable/disable, set password, delete)
- Manage client roles (get, assign/remove to users)
- Manage realm roles (get, create, delete, assign/remove to users and groups)
- Manage clients (get, create, delete, enable service accounts)
- Manage client scopes
- Manage realms
- Manage groups (create, delete, get, add/remove users)
- Token management (get service-account token, revoke token)
- Built-in retry policy via Polly
- Auth handler that automatically attaches Bearer tokens to requests
- Fully supports
IHttpClientFactoryand dependency injection
Requirements
- .NET 8+
- A running Keycloak server (v21+)
- A confidential client with Service Accounts Enabled
Installation
dotnet add package Keycloak.Net.Sdk
Configuration
1. appsettings.json
"keycloak": {
"ServerUrl": "https://your-keycloak-host/",
"RealmName": "your-realm",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"ClientUuid": "your-client-uuid",
"AdminUsername": "admin",
"AdminPassword": "admin-password",
"NumberOfRetries": 3,
"DelayBetweenRetryRequestsInSeconds": 2
}
| Field | Description |
|---|---|
ServerUrl |
Keycloak base URL (include trailing slash) |
RealmName |
The realm your client belongs to |
ClientId |
Client ID (used for service-account token requests) |
ClientSecret |
Client secret |
ClientUuid |
Client UUID (used in Admin API calls) |
AdminUsername |
Master realm admin username (for realm management) |
AdminPassword |
Master realm admin password |
NumberOfRetries |
Polly retry count (default: 3) |
DelayBetweenRetryRequestsInSeconds |
Delay between retries (default: 2) |
2. Register Services
builder.Services.AddKeycloak(builder.Configuration);
Usage
Inject the interface you need:
public class MyService(IUserManagement users, IRoleManagement roles)
{
public async Task CreateAndAssignAsync()
{
var signup = await users.SignupAsync(new SignupRequestDto
{
Username = "john.doe",
Email = "john@example.com",
FirstName = "John",
LastName = "Doe",
Password = "Secret@123"
});
await roles.AssignClientRoleToUser(userId: signup.Response.Id, roleId: "role-uuid");
}
}
Use IRoleManagement for both client roles and realm roles:
public class RoleService(IRoleManagement roles)
{
// Realm role CRUD
public async Task CreateRealmRoleAsync()
{
await roles.CreateRealmRoleAsync(new CreateRealmRoleRequestDto
{
Name = "admin",
Description = "Full access role"
});
}
// Assign a realm role to a user
public async Task AssignRealmRoleToUserAsync(string userId, string roleId, string roleName)
{
await roles.AssignRealmRoleToUserAsync(userId, roleId, roleName);
}
// Assign a realm role to a group
public async Task AssignRealmRoleToGroupAsync(string groupId, string roleId, string roleName)
{
await roles.AssignRealmRoleToGroupAsync(groupId, roleId, roleName);
}
}
Or use IGroupManagement to organize users into groups:
public class GroupService(IGroupManagement groups)
{
public async Task AssignUserToGroupAsync(string userId, string groupId)
{
await groups.AddUserToGroupAsync(userId, groupId);
}
public async Task<List<GroupResponseDto>> GetUserGroupsAsync(string userId)
{
var result = await groups.GetUserGroupsAsync(userId);
return result.Response;
}
}
Available Interfaces
| Interface | Responsibilities |
|---|---|
IUserManagement |
Sign up, sign in, get user, enable/disable, set password, delete |
IRoleManagement |
Client roles: get, assign/remove to users. Realm roles: get, create, delete, assign/remove to users and groups |
IClientManagement |
Get clients, get client scopes, create/delete client, enable service accounts |
IRealmManagement |
Create realm |
ITokenManagement |
Get service-account token, revoke token |
IGroupManagement |
Create/delete group, get groups, add/remove user from group, get user's groups |
Running Tests
Unit Tests
Unit tests use a fake HttpMessageHandler no external dependencies required.
dotnet test Keycloak.Net.Sdk.UnitTests/Keycloak.Net.Sdk.UnitTests.csproj
Integration Tests
Integration tests spin up a real Keycloak instance via Testcontainers. Docker must be running.
dotnet test Keycloak.Net.Sdk.IntegrationTests/Keycloak.Net.Sdk.IntegrationTests.csproj
The fixture automatically handles the full setup sequence:
- Starts a Keycloak container
- Creates a dedicated test realm
- Creates a confidential client with service accounts
- Grants realm-admin role to the service account
- Creates a test user, client role, realm role, and group
The first run pulls the Keycloak Docker image (~500 MB). Subsequent runs reuse the cached image.
All Tests
dotnet test
Project Structure
Keycloak.Net.Sdk/ # SDK source
├── Athentications/ # TokenProvider, TokenManagement, KeycloakAuthHandler
├── Clients/ # ClientManagement + DTOs
├── Configurations/ # KeycloakConfiguration
├── Contracts/ # Shared response types (KeycloakBaseResponse)
├── Extensions/ # ServiceRegistrations, ExceptionHandler
├── Groups/ # GroupManagement + DTOs
├── Realms/ # RealmManagement
├── Roles/ # RoleManagement + DTOs
└── Users/ # UserManagement + DTOs
Keycloak.Net.Sdk.UnitTests/ # Unit tests (Moq, FakeHttpMessageHandler)
Keycloak.Net.Sdk.IntegrationTests/ # Integration tests (Testcontainers.Keycloak)
License
Contact
Questions or feedback: miladrivandi73@gmail.com or open an issue.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Http.Polly (>= 8.0.15)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.3)
- Microsoft.Extensions.Options (>= 9.0.3)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Keycloak.Net.Sdk:
| Package | Downloads |
|---|---|
|
Keycloak.Net.Sdk.Aspire
.NET Aspire client integration for Keycloak.Net.Sdk — wires the SDK into a dependent project using the Aspire-injected connection string |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 1.5.0 | 44 | 6/20/2026 | |
| 1.4.1 | 114 | 6/8/2026 | |
| 1.3.0 | 96 | 6/3/2026 | |
| 1.2.0 | 100 | 5/29/2026 | |
| 1.1.2 | 105 | 5/28/2026 | |
| 1.1.1 | 282 | 4/21/2025 | |
| 1.0.3 | 285 | 4/13/2025 | |
| 1.0.1-rc06 | 526 | 3/24/2025 | |
| 1.0.1-rc05 | 515 | 3/24/2025 | |
| 1.0.1-rc04 | 515 | 3/24/2025 | |
| 1.0.1-rc03 | 334 | 3/23/2025 | |
| 1.0.0 | 361 | 3/23/2025 |