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

.NET Web应用中Azure OIDC与Bearer Token共存认证异常排查

问题:.NET Web应用同时支持Azure OAuth和Bearer Token认证失败

在.NET Web应用中借助Azure实现OAuth和Bearer Token两种请求认证方式时,OAuth认证功能正常——访问带有[Authorize]特性的控制器路由时,会触发登录提示且认证可正常通过,但Bearer Token认证无法生效,需要让所有控制器同时支持这两种认证方式。

获取Bearer Token的PowerShell方法

Install-Module -Name MSAL.PS

$Token = Get-MsalToken -ClientId 'clientId' -TenantId 'tenantId'

$Token.AccessToken

当前Program.cs代码

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddJwtBearer(opt =>
        {
            var conf = new MicrosoftIdentityOptions();
            builder.Configuration.GetSection(Constants.AzureAd).Bind(conf);
    
            opt.Audience = $"api://{conf.ClientId}";
            opt.Authority = $"{conf.Instance}{conf.TenantId}";
        })
        .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

    builder.Services.AddControllers();

    builder.Services.AddHttpForwarder();

    var app = builder.Build();

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();
    
    app.UseAuthentication();
    app.UseAuthorization();

    app.MapControllers();

    app.Run();
}

当前appsettings.json配置

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "qualified.domain.name",
    "TenantId": "",
    "ClientId": "",
    "CallbackPath": "/signin-oidc"
  }
}

解决方案

问题核心是默认认证方案设置为OpenIdConnectDefaults.AuthenticationScheme,且未配置授权策略同时允许两种认证方式,导致Bearer Token认证流程未被触发。需按以下步骤修改:

1. 调整认证服务配置

将默认认证方案改为CookieAuthenticationDefaults.AuthenticationScheme(OAuth流程最终通过Cookie保存身份),同时为JWT Bearer指定明确的方案名称,方便后续授权策略引用:

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddJwtBearer("Bearer", opt =>
    {
        var conf = new MicrosoftIdentityOptions();
        builder.Configuration.GetSection("AzureAd").Bind(conf);
    
        opt.Audience = $"api://{conf.ClientId}";
        opt.Authority = $"{conf.Instance}{conf.TenantId}/v2.0"; // 使用Azure AD v2端点
        // 配置Token验证参数,确保签名、受众、签发者有效性
        opt.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = $"{conf.Instance}{conf.TenantId}/v2.0",
            ValidateAudience = true,
            ValidAudience = $"api://{conf.ClientId}",
            ValidateLifetime = true
        };
    })
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

2. 配置全局授权策略

添加全局授权策略,让所有带[Authorize]特性的控制器同时接受Cookie(OAuth流程)和Bearer Token两种认证方式:

builder.Services.AddAuthorization(options =>
{
    var defaultPolicy = new AuthorizationPolicyBuilder()
        .AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme, "Bearer")
        .RequireAuthenticatedUser()
        .Build();
    options.DefaultPolicy = defaultPolicy;
});

3. 验证Token有效性

通过JWT解码工具(如本地离线解码)确认获取的Token符合要求:

  • aud字段需匹配api://{clientId}
  • iss字段需为https://login.microsoftonline.com/{tenantId}/v2.0

完整修改后的Program.cs

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using Microsoft.IdentityModel.Tokens;

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    // 配置双认证方案
    builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddJwtBearer("Bearer", opt =>
        {
            var conf = new MicrosoftIdentityOptions();
            builder.Configuration.GetSection("AzureAd").Bind(conf);
    
            opt.Audience = $"api://{conf.ClientId}";
            opt.Authority = $"{conf.Instance}{conf.TenantId}/v2.0";
            opt.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = $"{conf.Instance}{conf.TenantId}/v2.0",
                ValidateAudience = true,
                ValidAudience = $"api://{conf.ClientId}",
                ValidateLifetime = true
            };
        })
        .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

    // 配置全局授权策略
    builder.Services.AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme, "Bearer")
            .RequireAuthenticatedUser()
            .Build();
    });

    builder.Services.AddControllers();
    builder.Services.AddHttpForwarder();

    var app = builder.Build();

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();
    
    app.UseAuthentication();
    app.UseAuthorization();

    app.MapControllers();

    app.Run();
}

内容的提问来源于stack exchange,提问作者Node.JS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:33:12