Xzawed.Keycloak.Sdk
1.0.1
See the version list below for details.
dotnet add package Xzawed.Keycloak.Sdk --version 1.0.1
NuGet\Install-Package Xzawed.Keycloak.Sdk -Version 1.0.1
<PackageReference Include="Xzawed.Keycloak.Sdk" Version="1.0.1" />
<PackageVersion Include="Xzawed.Keycloak.Sdk" Version="1.0.1" />
<PackageReference Include="Xzawed.Keycloak.Sdk" />
paket add Xzawed.Keycloak.Sdk --version 1.0.1
#r "nuget: Xzawed.Keycloak.Sdk, 1.0.1"
#:package Xzawed.Keycloak.Sdk@1.0.1
#addin nuget:?package=Xzawed.Keycloak.Sdk&version=1.0.1
#tool nuget:?package=Xzawed.Keycloak.Sdk&version=1.0.1
Keycloak SDK for .NET
An async-first Keycloak client library for .NET that covers both Authentication (OIDC / OAuth2) and the Admin REST API behind one consistent facade.
Part of a nine-language polyglot SDK (Java · Python · Node · Go · C# · PHP · Rust · Ruby · Kotlin) whose concepts, layers, and flows are isomorphic across every language — github.com/xzawed/KeyCloakSDK.
1.0.1is on NuGet — a patch release of security and correctness fixes on top of1.0.0, the first release carrying the stability guarantee set out under Versioning and support below. A baredotnet add package Xzawed.Keycloak.Sdkresolves it. It stops the PKCE verifier and tokens leaking through the default serializer (present in1.0.0), caps JWKS and discovery response sizes, stops an empty200JWKS key set from replacing a good cached one, backs off failed JWKS fetches, and no longer returns a token response of the wrong shape as a success. ⚠️ AServerUrlthat is not an absolute http(s) URL is now rejected up front with aKeycloakConfigException, instead of escaping as aUriFormatExceptionon the first call.
Requirements
- .NET 8+ — the package targets
net8.0. - A Keycloak server to connect to (integration-tested against Keycloak 26.6).
Every network method returns Task<T> and takes a trailing CancellationToken ct = default; only CreateAuthorizationRequest is synchronous, because it needs no network.
Install
dotnet add package Xzawed.Keycloak.Sdk
The root namespace is Xzawed.Keycloak (Admin resources live in Xzawed.Keycloak.Admin).
Quickstart
using Keycloak.AuthServices.Sdk.Admin.Models;
using Xzawed.Keycloak;
var config = new KeycloakConfig
{
ServerUrl = "https://kc.example.com",
Realm = "myrealm",
ClientId = "admin-cli",
ClientSecret = "changeme", // load from an env var / secret manager
};
// await using: DisposeAsync() releases the auth resources and, if used, the admin client.
await using var kc = KeycloakClient.Create(config);
// 1. Get a token (client-credentials grant). TokenSet.ToString() masks the tokens as "***".
var tokens = await kc.Auth.ClientCredentialsTokenAsync();
Console.WriteLine(tokens);
// 2. Validate it (hardened, see below).
var vt = await kc.Auth.ValidateAsync(tokens.AccessToken);
Console.WriteLine($"subject={vt.Subject} aud=[{string.Join(",", vt.Audience)}]");
// 3. Call the Admin API. The admin facade is built lazily on first AdminAsync().
var admin = await kc.AdminAsync();
var userId = await admin.Users.CreateAsync(new UserRepresentation { Username = "alice", Enabled = true });
Console.WriteLine($"created userId={userId}");
Audience — validation requires the token's
audto containClientId. A stock realm does not put the client id in a client-credentials token'saud, so on a default realm either setExpectedAudience = "my-api"to the audience your realm issues, or add an Audience protocol mapper to the client in Keycloak.
Dependency injection is optional — KeycloakClient.Create(config) works standalone. If you do use a container, register the client as a singleton:
builder.Services.AddKeycloak(config); // registers KeycloakConfig + KeycloakClient as singletons
Admin failures surface as KeycloakNotFoundException / KeycloakConflictException / KeycloakForbiddenException (all carrying KeycloakAdminException.StatusCode), or KeycloakTransportException on a network failure.
Security defaults
- Algorithm pinning — the accepted signature algorithms are fixed by config (
RS256by default);alg: noneand unsigned tokens are rejected.Microsoft.IdentityModelleavesValidAlgorithmsunset, which accepts every algorithm it supports, so the SDK pins it explicitly. - Strict claim checks — exact
issmatch,audcontainment check, mandatoryexp, and a bounded clock skew (30s by default, down from the library's 5 minutes). - Rate-limited JWKS refetch — key sets are cached and refetches are throttled to a minimum interval (
JwtValidatorOptions.RefreshIntervalSeconds, 30s by default — the same value as the other eight SDKs). Read this one precisely: unlike its sibling SDKs, this one cannot promise that a bad signature never causes a refetch.Microsoft.IdentityModeltreats signature-validation failure as a possible key rotation and refreshes through itsConfigurationManager, and that behaviour cannot be disabled without giving up the manager entirely. The refresh interval is what bounds the amplification — measured, 6 forged tokens produce 1 extra fetch, not 6. A failed fetch is bounded separately: consecutive failures back off exponentially (0.2s, doubling, capped at 5s, with jitter), and inside that window the SDK fails fast without contacting the IdP. So a cold cache during an IdP outage no longer turns every validation into a request (measured: 20 attempts → 2 requests, down from 40 — this lane spends two requests per attempt, so one window costs two). ⚠️ The SDK never sleeps — it returns the error immediately, so retry pacing stays the caller's decision. - Secret handling —
KeycloakConfig,TokenSetandAuthorizationRequestmask secrets, tokens and the PKCECodeVerifieras***inToString()and JSON serialization, and TLS verification is on by default.
Masking covers ToString() and the types' JSON converters. It does not cover Serilog-style destructuring — {@Config} reads the properties directly and will print the raw secret, so log these three types with {Config}, not {@Config}.
Versioning and support
This SDK is 1.0 and follows SemVer: a breaking change to the public API requires a major bump. That promise is machine-backed — CI diffs this lane's public API against the previously published artifact on every build (the .NET SDK’s Package Validation, run during dotnet pack), and a removal or an incompatible change fails the build. ⚠️ The gate compares the API surface. A change that leaves the surface identical but alters behaviour is not caught by it, so read the release notes before upgrading.
Only the newest released version of each language SDK receives security fixes; there are no long-term-support lines and older releases are not backported to.
Each of the nine languages versions independently. All nine reached 1.0.0 in the same release wave because they earned the same guarantee at the same time — they do not move in lockstep afterwards.
Documentation
- Project overview — all nine languages, what is identical and what is not
- Changelog — read this before upgrading; breaking changes are listed per language
- Getting started — install and quickstart for this language
- Compatibility — which Keycloak server range and base libraries each published version shipped against
- Deploying a Keycloak server
- Security policy
License
Apache-2.0 — see LICENSE.
| 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
- Duende.IdentityModel (>= 8.1.0)
- Keycloak.AuthServices.Sdk (>= 2.7.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.20)
- Microsoft.IdentityModel.JsonWebTokens (>= 8.23.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.23.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.