EbrahimMansur.Dpop.AspNetCore 0.1.1

dotnet add package EbrahimMansur.Dpop.AspNetCore --version 0.1.1
                    
NuGet\Install-Package EbrahimMansur.Dpop.AspNetCore -Version 0.1.1
                    
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="EbrahimMansur.Dpop.AspNetCore" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EbrahimMansur.Dpop.AspNetCore" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="EbrahimMansur.Dpop.AspNetCore" />
                    
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 EbrahimMansur.Dpop.AspNetCore --version 0.1.1
                    
#r "nuget: EbrahimMansur.Dpop.AspNetCore, 0.1.1"
                    
#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 EbrahimMansur.Dpop.AspNetCore@0.1.1
                    
#: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=EbrahimMansur.Dpop.AspNetCore&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=EbrahimMansur.Dpop.AspNetCore&version=0.1.1
                    
Install as a Cake Tool

EbrahimMansur.Dpop.AspNetCore

ASP.NET Core integration for EbrahimMansur.Dpop, implementing DPoP (RFC 9449) sender-constrained access tokens on top of your existing JWT Bearer authentication — without replacing or duplicating it.

Install

dotnet add package EbrahimMansur.Dpop.AspNetCore

5-minute setup

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(/* your existing configuration */);

builder.Services.AddDpop(options =>
{
    options.Mode = DpopMode.Optional; // existing Bearer-only endpoints are unaffected
});

var app = builder.Build();

// Required for correct `htu` validation behind a reverse proxy — see "Reverse proxies" below.
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost,
});

app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/orders", () => Results.Ok(new[] { "order-1" }))
   .RequireAuthorization()
   .RequireDpop();

app.MapControllers();

app.Run();
[Authorize]
[RequireDpop]
public class OrdersController : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok(new[] { "order-1" });
}

Installing the package and calling AddDpop() alone does not require DPoP on any endpoint — existing Bearer-only endpoints keep working unchanged. DPoP is enforced only where you explicitly add .RequireDpop() or [RequireDpop], or when you set DpopOptions.Mode = DpopMode.Required globally.

How it works

The DPoP requirement is implemented as an ASP.NET Core authorization requirement, running after your existing authentication scheme (e.g. JWT Bearer) has already populated HttpContext.User. DPoP validation never touches or replaces token authentication — it only adds an extra proof-of-possession check on top of it, reading the access token's cnf claim to bind the proof's key to the token.

Failures are translated into a 401 response with a WWW-Authenticate: DPoP ... challenge header (and, when nonce enforcement is enabled, a DPoP-Nonce header) instead of the framework's default 403. Ordinary authorization failures (e.g. missing roles) are unaffected.

Reverse proxies

DPoP validates the request's htu (HTTP URI) against the externally visible URI, not whatever Kestrel sees internally. Behind a reverse proxy (NGINX, Kong, an API gateway, Kubernetes ingress), you must configure UseForwardedHeaders with a KnownProxies/KnownNetworks scoped to your actual trusted proxy — never left as an open wildcard — so HttpContext.Request.Scheme/Host reflect the client-facing values before DPoP validation runs.

Distributed deployments

The default IDpopReplayStore/IDpopNonceStore are in-memory and only correct for a single API instance. Once the API is horizontally scaled, register a distributed implementation of IDpopReplayStore/IDpopNonceStore (e.g. Redis- or IDistributedCache-backed) instead — the interfaces are designed to make this a drop-in replacement.

Source, issues, and contributing

Source code, issue tracker, and contributing guidelines live at github.com/ebrahimmansur/dpop-dotnet. Found a bug or unexpected HTTP status/header? Open an issue with a minimal repro, your package version, and the actual request/response you saw.

Product 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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1 118 8/10/2026
0.1.0 98 8/9/2026