You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core Web API中实现OAuth2.0 DPoP认证令牌?

ASP.NET Core Web API 实现 OAuth2.0 DPoP 令牌完整演示

一、环境准备

  • Visual Studio 2022(需安装「ASP.NET和Web开发」工作负载)
  • .NET 8 SDK(最新稳定版)

二、项目初始化与依赖安装

  1. 打开Visual Studio 2022,创建「ASP.NET Core Web API」项目,命名为DPoPWebAPI,选择.NET 8作为目标框架,可选择最小API模板(更简洁)。
  2. 右键项目→「管理NuGet程序包」,安装以下包:
    • Microsoft.AspNetCore.Authentication.JwtBearer(最新稳定版)
    • Microsoft.IdentityModel.Protocols.DPoP(微软官方DPoP协议实现包)

三、配置认证与授权(Program.cs)

替换默认Program.cs代码为以下内容:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Protocols.DPoP;
using Microsoft.Extensions.Caching.Memory;

var builder = WebApplication.CreateBuilder(args);

// 注册认证服务
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 替换为你的授权服务器地址(如IdentityServer6、Azure AD)
        options.Authority = "https://your-auth-server.com";
        // 替换为当前API的受众标识
        options.Audience = "your-api-resource-id";

        // 配置DPoP验证参数
        options.TokenValidationParameters.DPoPValidationParameters = new DPoPValidationParameters
        {
            // 验证DPoP令牌与当前请求的URI绑定
            ValidateBindingUri = true,
            // 用内存缓存存储Nonce,防止重放攻击
            NonceCache = new MemoryCache(new MemoryCacheOptions()),
            // Nonce有效期设为5分钟
            NonceLifetime = TimeSpan.FromMinutes(5)
        };

        // 无DPoP令牌时返回DPoP挑战头
        options.Events = new JwtBearerEvents
        {
            OnChallenge = context =>
            {
                context.Response.Headers.Append("WWW-Authenticate", "DPoP");
                return Task.CompletedTask;
            }
        };
    });

// 注册授权服务
builder.Services.AddAuthorization();

var app = builder.Build();

// 启用认证、授权中间件
app.UseAuthentication();
app.UseAuthorization();

// 受保护的API端点
app.MapGet("/api/protected", (HttpContext context) =>
{
    var userId = context.User.FindFirst("sub")?.Value;
    return Results.Ok(new 
    { 
        Message = "受保护端点访问成功", 
        AuthenticatedUserId = userId 
    });
})
.RequireAuthorization();

// 生成DPoP Nonce的端点(若授权服务器未提供,可自行实现)
app.MapGet("/api/dpop-nonce", (IMemoryCache cache) =>
{
    var nonce = DPoPNonceGenerator.GenerateNonce();
    cache.Set(nonce, DateTime.UtcNow, TimeSpan.FromMinutes(5));
    return Results.Ok(new { Nonce = nonce });
});

app.Run();

四、客户端请求演示(Postman操作步骤)

  1. 生成客户端密钥对:用代码或OpenSSL生成RSA/EC密钥对(私钥由客户端安全存储,公钥需同步到授权服务器)。
  2. 获取普通JWT令牌:通过授权服务器的授权码流/客户端凭证流获取标准JWT访问令牌。
  3. 生成DPoP令牌:
    • 构造DPoP Payload,包含:
      • htu:当前API请求的完整URL(如https://localhost:5001/api/protected)
      • htm:请求方法(如GET)
      • nonce:从/api/dpop-nonce获取的随机值
      • iat:当前时间戳
      • jti:唯一标识符
    • 用客户端私钥以RS256/ES256算法签名Payload,得到DPoP令牌。
  4. 发送请求:
    • 请求头添加:
      • Authorization: DPoP <你的JWT访问令牌>
      • DPoP: <生成的DPoP令牌>
    • 发送GET请求到https://localhost:5001/api/protected,验证通过后将返回成功响应。

五、核心注意事项

  • DPoP作用:将令牌与客户端密钥对绑定,避免令牌被盗用后重放,提升安全等级。
  • 授权服务器要求:需使用支持DPoP的授权服务器(如IdentityServer6、Azure AD),并在授权服务器端开启DPoP配置。
  • Nonce机制:必须验证Nonce防止重放攻击,建议从授权服务器获取Nonce而非自行生成。
  • 密钥安全:客户端私钥需加密存储,禁止明文暴露,生产环境建议使用硬件安全模块(HSM)托管密钥。

内容的提问来源于stack exchange,提问作者Ganesh Lawand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:42:27