升级至.NET 6后OnRedirectToIdentityProvider事件未触发问题排查
.NET 6升级后OpenIdConnect OnRedirectToIdentityProvider事件未触发问题
问题描述
项目从.NET Core 2.2升级至.NET 6后,OpenIdConnect配置中的OnRedirectToIdentityProvider事件未被触发,无任何报错信息,但该事件在原.NET Core 2.2环境下可正常运行。
相关代码配置
Identity Server启动代码
app.UseForwardedHeaders().UseHttpsRedirection(); app.UseResponseCompression(); if (env.IsDevelopment()) app.UseDeveloperExceptionPage(); else { app.UseExceptionHandler("/Home/Error"); app.UseStatusCodePagesWithReExecute("/Home/Error/{0}"); app.ConfigureHttpToHttpsRewrites(env); } app.UseRouting(); app.UseIdentityServer(); app.UseStaticFiles(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute(name: "default", pattern: "{controller}/{action=Index}/{id?}"); });
认证配置方法
public static void ConfigureAuthentication(this IServiceCollection services, IConfigurationRoot configuration) { services .AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => { options.ReturnUrlParameter = "somePar"; }) .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.Authority = "IdentityServer"; options.ResponseType = OidcConstants.ResponseTypes.CodeIdToken; options.ClientId = "ClientId"; options.ClientSecret = "ClientSecret"; options.RequireHttpsMetadata = false; options.SignedOutRedirectUri = websiteSettings.GetValue<string>("Home"); options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Add("some"); options.SaveTokens = true; options.RemoteAuthenticationTimeout = TimeSpan.FromMinutes(30); options.TokenValidationParameters.RoleClaimType = "role"; options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = context => { // breakpoint doesn`t call // code.. return Task.CompletedTask; } }; }); }
控制器相关代码(同一类中的方法)
public async Task<ActionResult> T1Async(Guid idd) { if (User.Identity.IsAuthenticated) return RedirectToAction(nameof(CompleteAsync)); // code.. } [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] [HttpGet("complete/{requestId}")] public async Task<ActionResult> CompleteAsync(Guid requestId) { // some code.. }
Identity Server客户端配置
public static Client[] Get(Settings settings) { return new[] { new Client { ClientId = "clientId", ClientName = "clientName", ClientSecrets = { new Secret(secret.Sha256()) }, AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, AccessTokenType = AccessTokenType.Reference, Enabled = true, RequireConsent = false, AllowOfflineAccess = true, UpdateAccessTokenClaimsOnRefresh = true, AlwaysIncludeUserClaimsInIdToken = true, BackChannelLogoutUri = $"{settings.Home}/signout-oidc", PostLogoutRedirectUris = new List<string> { $"{settings.Home}/signout-callback-oidc" }, RedirectUris = new List<string> { $"{settings.Home}/signin-oidc" }, RefreshTokenUsage = TokenUsage.ReUse, RefreshTokenExpiration = TokenExpiration.Absolute, IdentityTokenLifetime = 300, AuthorizationCodeLifetime = 300, AccessTokenLifetime = 3600, AbsoluteRefreshTokenLifetime = 3600, RequirePkce = false, AllowedScopes = {"openid","profile"} } }; }
解决方案
1. 修正客户端中间件顺序
.NET 6对中间件顺序要求更严格,需确保UseAuthentication和UseAuthorization放置在正确位置。修改客户端启动代码:
app.UseForwardedHeaders().UseHttpsRedirection(); app.UseResponseCompression(); if (env.IsDevelopment()) app.UseDeveloperExceptionPage(); else { app.UseExceptionHandler("/Home/Error"); app.UseStatusCodePagesWithReExecute("/Home/Error/{0}"); app.ConfigureHttpToHttpsRewrites(env); } app.UseRouting(); // 添加认证和授权中间件,顺序不可颠倒 app.UseAuthentication(); app.UseAuthorization(); app.UseStaticFiles(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute(name: "default", pattern: "{controller}/{action=Index}/{id?}"); });
2. 调整认证配置的默认Scheme
原配置中DefaultAuthenticateScheme设置为OpenIdConnect会导致流程冲突,改为指定DefaultChallengeScheme,确保未认证时触发OIDC跳转:
services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; // 替换DefaultAuthenticateScheme为DefaultChallengeScheme options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; })
3. 修复代码语法问题
检查并修正OpenIdConnect配置中的语法错误:比如原代码中options.Authority = "IdentityServer");多了闭合括号;同时OnRedirectToIdentityProvider事件方法需返回Task.CompletedTask以符合异步方法要求。
4. 验证客户端地址配置
确保Identity Server客户端配置中的RedirectUris、PostLogoutRedirectUris等地址与客户端实际运行地址完全匹配(包括协议、域名、端口),.NET 6对地址验证的严格性有所提升。
内容的提问来源于stack exchange,提问作者lucianobonde
相关产品推荐
相关产品推荐

