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

升级至.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:48:00