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

ASP.NET Core多身份验证配置问题:第二种OIDC方案失效

ASP.NET Core 多OpenID Connect身份验证回调路由异常问题

当前为ASP.NET Core应用配置了两种OpenID Connect身份验证方案,配置代码如下:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultScheme = "FIRST_OR_SECOND";
    options.DefaultChallengeScheme = "FIRST_OR_SECOND";
}).AddOpenIdConnect("FIRST", options => {
    options.Authority = "https://domain.login.com/domain.onmicrosoft.com/FIRST_SIGNIN/v2.0";
    options.ClientId = _webConfig.FIRST.ClientId;
    options.ClientSecret = _webConfig.FIRST.ClientSecret;
    options.Scope.Add(_webConfig.FIRST.ClientId);
    // 其他配置...
    options.Events = new OpenIdConnectEvents {
        OnRedirectToIdentityProvider = async ctxt => {...},
        OnMessageReceived = async ctxt => {...}
        // 其他事件...
    };
}).AddOpenIdConnect("SECOND", options => {
    options.Authority = "https://domain.login.com/domain.onmicrosoft.com/SECOND_SIGNIN/v2.0";
    options.ClientId = _webConfig.SECOND.ClientId;
    options.ClientSecret = _webConfig.SECOND.ClientSecret;
    options.Scope.Add(_webConfig.SECOND.ClientId);
    // 其他配置...
    options.Events = new OpenIdConnectEvents {
        OnRedirectToIdentityProvider = async ctxt => {...},
        OnMessageReceived = async ctxt => {...}
        // 其他事件...
    };
}).AddPolicyScheme("FIRST_OR_SECOND", "FIRST_OR_SECOND", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        string path = context.Request.Path;
        if (!string.IsNullOrEmpty(path) && path.Contains("/SECOND_LOGIN"))
        {
            return "SECOND";
        }
        return "FIRST";
    };
}).AddCookie(options =>
{
    options.Cookie.SameSite = SameSiteMode.None;
    options.SlidingExpiration = true;
});

问题现象

  • 第一种验证方案可正常工作,第二种方案无法完成回调;交换两个AddOpenIdConnect的注册顺序后,问题反转(原第二种正常,第一种异常)
  • 核心异常:第二种方案的OnRedirectToIdentityProvider事件能正常触发,但身份提供商返回回调消息时,请求被导向第一种方案的OnMessageReceived事件

解决方案

1. 为每个OIDC方案配置独立回调路径

ASP.NET Core默认会将所有OIDC回调请求匹配到第一个注册的OIDC方案,因此需要为每个方案指定唯一的CallbackPath:

// 第一种方案配置
.AddOpenIdConnect("FIRST", options => {
    // 原有配置...
    options.CallbackPath = "/signin-first"; // 专属回调路径
    // 事件配置...
})
// 第二种方案配置
.AddOpenIdConnect("SECOND", options => {
    // 原有配置...
    options.CallbackPath = "/signin-second"; // 专属回调路径
    // 事件配置...
})

同时需要登录身份提供商后台(如Azure AD),将对应应用的回调URL更新为:

  • 第一种方案:https://你的应用域名/signin-first
  • 第二种方案:https://你的应用域名/signin-second

2. 明确指定回调处理的验证方案

如果无法修改回调路径,可在自定义回调Action中明确指定使用的验证方案:

[HttpGet("/SECOND_LOGIN/callback")]
public async Task<IActionResult> SecondLoginCallback()
{
    // 明确使用SECOND方案验证回调
    var authResult = await HttpContext.AuthenticateAsync("SECOND");
    if (authResult.Succeeded)
    {
        // 将用户信息写入Cookie
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, authResult.Principal);
        return RedirectToAction("Index", "Home");
    }
    return BadRequest("登录验证失败");
}

此方式需将身份提供商的回调URL修改为指向该自定义Action路径。

3. 验证PolicyScheme转发逻辑

PolicyScheme的ForwardDefaultSelector主要用于挑战(Challenge)阶段的方案选择,回调请求需要直接匹配对应OIDC方案,因此独立回调路径是最可靠的解决方式,避免转发逻辑干扰回调处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:15:38