ASP.NET MVC集成Microsoft Identity Platform遇IDX21323错误求助
问题背景
ASP.NET MVC应用已在Azure AD注册,对接Microsoft Identity Platform,完成web.config和Startup.cs配置后,遇到Nonce验证失败错误。
现有配置
web.config配置
ClientId: XXXXX-XXXXX-XXXX-3b59 TenantID: XXXX-XXXX-XXXX-d086 Authority: https://login.microsoftonline.com/{0}/v2.0 redirectUri: http://localhost/XXXX
<system.web> <sessionState cookieSameSite="None"/> <httpCookies requireSSL="true"/> </system.web>
Startup.cs配置
// The Client ID is used by the application to uniquely identify itself to Azure AD. string clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"]; // RedirectUri is the URL where the user will be redirected to after they sign in. string redirectUri = System.Configuration.ConfigurationManager.AppSettings["redirectUri"]; // Tenant is the tenant ID (e.g. contoso.onmicrosoft.com, or 'common' for multi-tenant) static string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"]; string authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, System.ConfigurationManager.AppSettings["Authority"], tenant); public void Configuration(IAppBuilder app) { IdentityModelEventSource.ShowPII = true; app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationType = "ApplicationCookie", CookieSameSite = SameSiteMode.None, CookieSecure = CookieSecureOption.Always, CookieHttpOnly = true }); OpenIdConnectProtocolValidator dd = new OpenIdConnectProtocolValidator() { RequireNonce = false, }; app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { // Sets the ClientId, authority, RedirectUri as obtained from web.config ClientId = clientId, Authority = authority, RedirectUri = redirectUri, // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page PostLogoutRedirectUri = redirectUri, Scope = OpenIdConnectScope.OpenIdProfile, // ResponseType is set to request the code id_token - which contains basic information about the signed-in user ResponseType = OpenIdConnectResponseType.CodeIdToken, TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = false }, // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method Notifications = new OpenIdConnectAuthenticationNotifications { AuthenticationFailed = OnAuthenticationFailed } } ); } private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) { context.HandleResponse(); context.Response.Redirect("/?errormessage=" + context.Exception.Message); return Task.FromResult(0); }
错误详情
IDX21323: RequireNonce 为 'True'。OpenIdConnectProtocolValidationContext.Nonce 为 null,OpenIdConnectProtocol.ValidatedIdToken.Payload.Nonce 不为 null。Nonce 无法验证。如果无需检查Nonce,请将OpenIdConnectProtocolValidator.RequireNonce设置为'false'。注意如果发现'nonce',仍会对其进行评估。
修复方案
1. 关联自定义Nonce验证器
你已经创建了RequireNonce=false的验证器,但未将其关联到OpenIdConnect认证选项中,导致默认验证器仍生效。需在OpenIdConnectAuthenticationOptions中添加赋值:
app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { // 其他原有配置... ProtocolValidator = dd, // 关联自定义验证器 // 其他原有配置... } );
2. 修正CookieSecure配置(针对localhost调试)
你的redirectUri是http://localhost,但CookieAuthentication设置了CookieSecure = CookieSecureOption.Always,这会导致浏览器拒绝在非HTTPS环境下保存Cookie,而Nonce值存储在Cookie中,这是Nonce为null的核心原因之一。调试时修改为:
CookieSecure = CookieSecureOption.SameAsRequest
生产环境可改回CookieSecureOption.Always。
3. 统一认证类型标识
当前代码中app.SetDefaultSignInAsAuthenticationType使用CookieAuthenticationDefaults.AuthenticationType,但CookieAuthentication的AuthenticationType设为"ApplicationCookie",两者不一致会导致认证上下文异常,修正为:
app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, CookieSameSite = SameSiteMode.None, CookieSecure = CookieSecureOption.SameAsRequest, CookieHttpOnly = true });
最终修改后的Startup.cs关键片段
public void Configuration(IAppBuilder app) { IdentityModelEventSource.ShowPII = true; app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, CookieSameSite = SameSiteMode.None, CookieSecure = CookieSecureOption.SameAsRequest, CookieHttpOnly = true }); OpenIdConnectProtocolValidator nonceValidator = new OpenIdConnectProtocolValidator() { RequireNonce = false, }; app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = clientId, Authority = authority, RedirectUri = redirectUri, PostLogoutRedirectUri = redirectUri, Scope = OpenIdConnectScope.OpenIdProfile, ResponseType = OpenIdConnectResponseType.CodeIdToken, ProtocolValidator = nonceValidator, TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = false }, Notifications = new OpenIdConnectAuthenticationNotifications { AuthenticationFailed = OnAuthenticationFailed } } ); }
内容的提问来源于stack exchange,提问作者Akshay Bagi

