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

如何在OpenIdDict授权码流中禁用.AspNetCore.OpenIdConnect.Nonce Cookie?

关于OpenIdDict/OIDC授权码流中Nonce的两个问题解答

1. 能否仅通过URL传递Nonce,不生成.AspNetCore.OpenIdConnect.Nonce Cookie?

可以实现,但需要自定义Nonce的生成与验证逻辑,绕过OIDC中间件默认的Cookie存储机制。默认情况下,AspNetCore OIDC中间件会自动生成Nonce并存入Cookie用于重放攻击防护,若要仅通过URL传递,可将Nonce嵌入加密的state参数中(state本身会由中间件加密处理,安全性有保障),具体步骤如下:

  • 在重定向到Azure AD前,自定义生成Nonce并存储到AuthenticationProperties(最终会加密到state参数中)
  • 在回调验证阶段,从加密的state中提取Nonce,与ID Token中的Nonce进行比对
  • 禁用中间件自动生成的Nonce Cookie

示例代码(在ConfigureServices中配置OIDC):

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.ClientId = "你的Azure AD客户端ID";
    options.Authority = "https://login.microsoftonline.com/你的租户ID/v2.0";
    options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
    options.Scope.Add("openid");
    options.Scope.Add("profile");

    // 自定义Nonce生成逻辑:重定向到IDP前生成Nonce并存入state
    options.Events.OnRedirectToIdentityProvider = context =>
    {
        if (string.IsNullOrEmpty(context.ProtocolMessage.Nonce))
        {
            // 生成自定义Nonce(示例:无短横线的Guid)
            var customNonce = Guid.NewGuid().ToString("N");
            context.ProtocolMessage.Nonce = customNonce;
            
            // 将Nonce存入AuthenticationProperties,会被加密到state中
            context.Properties.SetString("CustomNonce", customNonce);
        }
        return Task.CompletedTask;
    };

    // 自定义Nonce验证逻辑:从回调的state中提取Nonce并验证
    options.Events.OnTokenValidated = context =>
    {
        var customNonce = context.Properties.GetString("CustomNonce");
        var idTokenNonce = (context.SecurityToken as JwtSecurityToken)?.Payload.Nonce;

        if (!string.Equals(customNonce, idTokenNonce, StringComparison.Ordinal))
        {
            context.Fail("Nonce验证失败");
        }

        // 验证后移除存储的Nonce
        context.Properties.Items.Remove("CustomNonce");
        return Task.CompletedTask;
    };

    // 禁用自动生成的Nonce Cookie:设置过期时间为0使其失效
    options.NonceCookie.ExpireTimeSpan = TimeSpan.Zero;
});

2. 能否控制Nonce的内容?

完全可以,通过自定义Nonce生成逻辑即可控制其格式与内容。针对你遇到的WAF因Cookie包含短横线拦截的问题,可通过两种方式解决:

方式一:自定义无短横线的Nonce内容

在OnRedirectToIdentityProvider事件中替换默认生成的Nonce,生成不含短横线的字符串:

options.Events.OnRedirectToIdentityProvider = context =>
{
    // 生成16位无短横线的随机字母数字作为Nonce
    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    var random = new Random();
    var customNonce = new string(Enumerable.Repeat(chars, 16)
        .Select(s => s[random.Next(s.Length)]).ToArray());
    
    context.ProtocolMessage.Nonce = customNonce;
    return Task.CompletedTask;
};

方式二:修改Nonce Cookie名称(移除短横线)

若不需要取消Cookie机制,仅需避免Cookie名称中的短横线,可直接修改Cookie名称:

// 生成无短横线的Nonce Cookie名称
options.NonceCookie.Name = ".AspNetCore.OpenIdConnect.Nonce" + Guid.NewGuid().ToString("N");

这样生成的Cookie名称不再包含短横线,可避免WAF拦截问题。


内容的提问来源于stack exchange,提问作者Alex Klaus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:05:27