如何在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
相关产品推荐
相关产品推荐

