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

升级Microsoft.Identity.Web.UI后Azure Web App的OpenIdConnect认证异常解决咨询

ASP.NET Core 3.1 + Microsoft.Identity.Web升级后Easy Auth兼容性问题解决方案

问题背景

我们有一个ASP.NET Core 3.1 Web应用,采用多种认证方案支持API和客户登录,原认证配置代码如下:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "smart";
    options.DefaultChallengeScheme = "smart";
})
.AddToken<TokenAuthenticationService>(options =>
{
    options.TokenFieldName = "Token";
}).AddPolicyScheme("smart", "Bearer or OpenIDConnect", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        string authHeader = context.Request.Headers["Authorization"];
        if (authHeader?.StartsWith("Bearer ") == true)
        {
            return TokenAuthenticationDefaults.AuthenticationScheme;
        }
        return OpenIdConnectDefaults.AuthenticationScheme;
    };
});

应用使用Azure App Service经典版Easy Auth功能,升级Microsoft.Identity.Web.UI NuGet包从0.4.0-preview到2.15.3后,出现异常:No authentication handler is registered for the scheme 'OpenIdConnect.'。经排查,原因是Microsoft.Identity.Web 1.2.0+版本检测到Easy Auth时,会自动将默认认证方案替换为AppServicesAuthenticationDefaults,不再默认注册OpenIdConnect方案。

解决方法

1. 显式注册OpenIdConnect认证处理器

由于Microsoft.Identity.Web不再自动注册OpenIdConnect方案,需手动添加对应的认证处理器。在原认证配置链中补充注册逻辑:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "smart";
    options.DefaultChallengeScheme = "smart";
})
.AddToken<TokenAuthenticationService>(options =>
{
    options.TokenFieldName = "Token";
})
// 显式注册OpenIdConnect方案
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    // 从配置文件读取Azure AD相关参数
    options.ClientId = Configuration["AzureAd:ClientId"];
    options.Authority = Configuration["AzureAd:Authority"];
    options.CallbackPath = Configuration["AzureAd:CallbackPath"];
    // 根据需求添加其他配置(如签名验证、范围等)
})
.AddPolicyScheme("smart", "Bearer or OpenIDConnect", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        string authHeader = context.Request.Headers["Authorization"];
        if (authHeader?.StartsWith("Bearer ") == true)
        {
            return TokenAuthenticationDefaults.AuthenticationScheme;
        }
        return OpenIdConnectDefaults.AuthenticationScheme;
    };
});

如果使用Microsoft.Identity.Web的扩展方法,也可以用以下方式注册:

.AddMicrosoftIdentityWebApp(Configuration, OpenIdConnectDefaults.AuthenticationScheme)

2. 禁用Microsoft.Identity.Web的Easy Auth自动替换逻辑

在appsettings.json中添加配置项,阻止Microsoft.Identity.Web自动替换默认认证方案:

"AzureAd": {
    "DisableAutomaticAuthenticationSchemeSelection": true,
    // 保留原有的Azure AD配置参数
    "ClientId": "your-client-id",
    "Authority": "your-authority",
    "CallbackPath": "/signin-oidc"
}

此配置会让Microsoft.Identity.Web尊重你手动设置的默认认证方案(即smart PolicyScheme),不再自动切换为AppServicesAuthenticationDefaults。

3. 调整PolicyScheme转发逻辑兼容Easy Auth

如果需要保留Easy Auth的自动处理逻辑,可以修改PolicyScheme的转发规则,同时注册AppServicesAuthentication方案:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "smart";
    options.DefaultChallengeScheme = "smart";
})
.AddToken<TokenAuthenticationService>(options =>
{
    options.TokenFieldName = "Token";
})
// 注册AppServicesAuthentication方案以支持Easy Auth
.AddAppServicesAuthentication()
.AddPolicyScheme("smart", "Bearer or OpenIDConnect or Easy Auth", options =>
{
    options.ForwardDefaultSelector = context =>
    {
        string authHeader = context.Request.Headers["Authorization"];
        if (authHeader?.StartsWith("Bearer ") == true)
        {
            return TokenAuthenticationDefaults.AuthenticationScheme;
        }
        // 检测Easy Auth请求头,转发到对应的方案
        if (!string.IsNullOrEmpty(context.Request.Headers["X-MS-CLIENT-PRINCIPAL-ID"]))
        {
            return AppServicesAuthenticationDefaults.AuthenticationScheme;
        }
        return OpenIdConnectDefaults.AuthenticationScheme;
    };
})
// 仍需显式注册OpenIdConnect方案
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.ClientId = Configuration["AzureAd:ClientId"];
    options.Authority = Configuration["AzureAd:Authority"];
    options.CallbackPath = Configuration["AzureAd:CallbackPath"];
});

复现问题的变通方法

本地模拟Easy Auth环境

  • 添加模拟请求头:在本地调试时,通过Postman或浏览器插件手动添加Easy Auth相关请求头(如X-MS-CLIENT-PRINCIPAL-ID、X-MS-CLIENT-PRINCIPAL-NAME),触发Microsoft.Identity.Web的Easy Auth检测逻辑。
  • 设置环境变量:在本地运行环境中设置WEBSITE_AUTH_ENABLED=True,模拟Azure App Service的认证启用状态,让Microsoft.Identity.Web自动触发方案替换逻辑。

使用临时Azure资源

如果允许创建临时资源,可以新建一个Azure App Service实例,启用Easy Auth(即使是新版,也能复现方案替换的核心逻辑),部署升级后的应用进行测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:13:21