Duende.Labs.IdentityModel 2026.1020.57

Prefix Reserved
dotnet add package Duende.Labs.IdentityModel --version 2026.1020.57
                    
NuGet\Install-Package Duende.Labs.IdentityModel -Version 2026.1020.57
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Duende.Labs.IdentityModel" Version="2026.1020.57" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Duende.Labs.IdentityModel" Version="2026.1020.57" />
                    
Directory.Packages.props
<PackageReference Include="Duende.Labs.IdentityModel" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Duende.Labs.IdentityModel --version 2026.1020.57
                    
#r "nuget: Duende.Labs.IdentityModel, 2026.1020.57"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Duende.Labs.IdentityModel@2026.1020.57
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Duende.Labs.IdentityModel&version=2026.1020.57
                    
Install as a Cake Addin
#tool nuget:?package=Duende.Labs.IdentityModel&version=2026.1020.57
                    
Install as a Cake Tool

IdentityModel for .NET

Modern OpenID Connect and OAuth 2.0 client library for .NET 10 and .NET Standard 2.0.

The package provides net10.0 and netstandard2.0 assets. Native AOT and trimming analysis are supported by the net10.0 build; the .NET Standard asset uses internal compatibility shims for APIs introduced after .NET Standard 2.0. Request options are target-specific: net10.0 exposes System.Net.Http.HttpRequestOptions, while netstandard2.0 exposes the library-owned Duende.IdentityModel.Protocol.RequestOptions. In both assets, values are copied onto the outgoing HttpRequestMessage (Options on .NET 5+, Properties on .NET Standard 2.0).

Installation

dotnet add package Duende.Labs.IdentityModel

Note This package is experimental/preview. For production scenarios, consider Duende.IdentityModel.

Typed client

IdentityModel uses named HttpClient instances and named options. Register an authority once:

services.AddIdentityModelClient(options =>
{
    options.Authority = new Uri("https://demo.duendesoftware.com");
    options.DefaultClientCredential = new ClientCredential("m2m", "secret");
    options.Scope = "api";
});

Inject IIdentityModelClientFactory and asynchronously create an initialized client:

public sealed class Worker(IIdentityModelClientFactory factory)
{
    public async Task RunAsync(CancellationToken ct)
    {
        var creation = await factory.CreateAsync(ct);
        if (!creation.IsSuccess)
        {
            // Inspect creation.Error.
            return;
        }

        var client = creation.Response;
        if (!client.SupportsClientCredentials)
        {
            return;
        }

        var token = await client.RequestClientCredentialsTokenAsync(ct);
    }
}

The factory retrieves and validates discovery, resolves protocol endpoints, and returns an initialized client. Its endpoints and capabilities only change when you call RefreshDiscoveryAsync. Calls do not require callers to copy endpoint URIs out of discovery or construct endpoint-bearing request objects.

Capabilities

The initialized client exposes capabilities such as SupportsClientCredentials, SupportsUserInfo, SupportsDeviceAuthorization, and SupportsPushedAuthorization.

Capability validation is strict by default. Strict mode checks endpoint presence and relevant advertised metadata, including grant types and client authentication methods. An unsupported call fails locally with ProtocolErrorType.UnsupportedFeature.

Providers with incomplete discovery documents can use relaxed mode:

services.AddIdentityModelClient(options =>
{
    options.Authority = new Uri("https://provider.example.com");
    options.CapabilityValidationMode = CapabilityValidationMode.Relaxed;
});

Relaxed mode requires a resolved endpoint but does not block a call because other advertised metadata is missing.

Endpoint overrides and limited clients

Explicit endpoint overrides take precedence over discovery and may be absolute or relative to the authority:

services.AddIdentityModelClient(options =>
{
    options.Authority = new Uri("https://provider.example.com");
    options.TokenEndpoint = new Uri("/oauth/token", UriKind.Relative);
});

If discovery fails but one or more explicit endpoints are usable, creation succeeds with a limited client. DiscoveryError preserves the failure and only explicitly configured capabilities are available. Creation fails when discovery fails and no usable override exists.

Named clients

services.AddIdentityModelClient("customers", options => { /* ... */ });
services.AddIdentityModelClient("partners", options => { /* ... */ });

var customers = await factory.CreateAsync("customers", ct);

Each factory call uses the current named options and creates a fresh client. The factory does not retain typed clients. Discovery documents are cached by URL, so clients that share an authority share one cached document, and each client still validates it against its own policy.

Per-call customization

Overloads accept a transform for operation-specific values:

var result = await client.RequestClientCredentialsTokenAsync(
    request => request with { Scope = "api.read" },
    ct);

The client supplies endpoint and configured defaults before invoking the transform.

HTTP handlers and resilience

AddIdentityModelClient returns the backing IHttpClientBuilder, so handlers apply to discovery and protocol requests:

services
    .AddIdentityModelClient(options => { /* ... */ })
    .AddHttpMessageHandler<MyHandler>()
    .AddStandardResilienceHandler();

Discovery and JSON Web Key Set caching

Discovery documents and JSON Web Key Sets are cached through HybridCache, so creating a client or reading keys usually doesn't hit the authority. Concurrent requests for the same document share one fetch, and a failed fetch or a document that fails validation is never cached. Entries are shared by URL across clients. The client that writes an entry on a miss or refresh sets its lifetime, so give named clients that share an authority or JWKS URL the same cache durations.

Option Default Description
CacheDiscovery true Cache the discovery document
DiscoveryCacheDuration 24 hours How long a discovery document stays cached
CacheJsonWebKeySet true Cache the JSON Web Key Set
JsonWebKeySetCacheDuration 1 hour How long a key set stays cached
JsonWebKeySetRefreshInterval 5 minutes Minimum time between forced key set refreshes for one URL. TimeSpan.Zero removes the limit

When a key rotates before the cache expires, call RefreshJsonWebKeySetAsync to fetch the set again and replace the cache entry. A token's kid is attacker-controlled, so forced refreshes are limited to one per JsonWebKeySetRefreshInterval. Within that window the call returns the cached set.

RefreshDiscoveryAsync fetches discovery again, replaces the cache entry, and updates the client's endpoints and Supports* flags in place. It also turns a limited client into a fully discovered one once the authority is reachable. A failed refresh leaves the client unchanged.

var keys = await client.GetJsonWebKeySetAsync(ct);
if (!keys.Response.Keys.Any(key => key.Kid == kid))
{
    keys = await client.RefreshJsonWebKeySetAsync(ct);
}

AddIdentityModelClient registers the default HybridCache. Register an IDistributedCache, such as Redis, to share cached documents across instances. To keep IdentityModel's entries apart from the rest of your application, register a keyed HybridCache under IdentityModelCacheKeys.DiscoveryCache or IdentityModelCacheKeys.JsonWebKeySetCache. Entries are tagged with IdentityModelCacheKeys.DiscoveryTag and IdentityModelCacheKeys.JsonWebKeySetTag, so RemoveByTagAsync clears them.

Prefer RFC 9111 HTTP caching? Turn off the built-in caches and add a caching handler to the IHttpClientBuilder. The BuiltInCaching sample shows the built-in caches in action. The Caching sample shows RFC 9111 HTTP caching with DamianH.HttpHybridCacheHandler, which honours the server's caching headers.

HybridCache reports trim and AOT warnings from its reflection-based JSON fallback serializer (dotnet/extensions#5624). IdentityModel only caches strings, which HybridCache serializes without reflection, so these warnings are safe to ignore in Native AOT apps.

Configuration binding

services.AddIdentityModelClient(builder.Configuration.GetSection("IdentityProvider"));

Recognized keys include Authority, ClientId, ClientSecret, ClientCredentialStyle, Scope, CapabilityValidationMode, the cache settings (CacheDiscovery, DiscoveryCacheDuration, CacheJsonWebKeySet, JsonWebKeySetCacheDuration, JsonWebKeySetRefreshInterval), and endpoint overrides. Durations use the invariant TimeSpan format, for example 01:00:00. Values are read explicitly to preserve trimming and Native AOT compatibility.

Features

The typed client supports:

  • Discovery and JSON Web Keys
  • Client credentials, authorization code, and refresh token requests
  • The obsolete password grant (DUENDEIM0001), only to migrate existing applications
  • Token introspection and revocation
  • UserInfo
  • Device authorization, device token requests, and device token polling
  • Pushed Authorization Requests and Rich Authorization Requests
  • CIBA backchannel authentication, token requests, and token polling
  • Dynamic client registration and RFC 7592 registration management

Generic SetBearerToken helpers remain available for setting an OAuth bearer token on an HttpClient or HttpRequestMessage.

License

IdentityModel is open source under the Apache 2.0 license.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Duende.Labs.IdentityModel:

Package Downloads
Duende.Labs.AccessTokenManagement

Automatic access token management for OAuth client credential flows

Duende.Labs.IdentityModel.OidcClient

RFC8252 compliant and certified OpenID Connect and OAuth 2.0 client library for native applications

Duende.Labs.IdentityModel.DependencyInjection

Dependency injection and IHttpClientFactory integration for Duende.Labs.IdentityModel

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2026.1020.57 77 10/20/2026
2026.1014.56 86 10/14/2026
2026.1009.55 93 10/9/2026
2026.1007.54 104 10/7/2026
2026.1001.53 104 10/1/2026
2026.922.37 111 9/22/2026
2026.806.21 141 8/6/2026
2026.804.20 131 8/4/2026
2026.729.19 130 7/29/2026
2026.729.18 116 7/29/2026
2026.729.17 117 7/29/2026
2026.728.16 119 7/28/2026
2026.728.15 126 7/28/2026
2026.727.14 927 7/27/2026
2026.727.13 114 7/27/2026
2026.726.12 156 7/26/2026
2026.725.11 930 7/25/2026
2026.724.10 132 7/24/2026
2026.724.9 119 7/24/2026
2026.724.8 107 7/24/2026
Loading failed