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

使用OpenId从Web App调用Web API时无法使用Authorize标签

.NET 4.8 Web App调用.NET 6 Web API添加[Authorize]后出现内部错误的解决方案

.NET 4.8的Web App已通过Azure AD OpenID完成认证,可正常调用.NET 6的Web API,但为Web API控制器添加[Authorize]标签后持续出现内部错误。


Web App - Startup.cs

private static string _clientId = Properties.Resource.ClientId;
private static string _aadInstance = EnsureTrailingSlash(Properties.Resource.AADInstance);
private static string _tenantId = Properties.Resource.TenantId;
private static string _RedirectUri = Properties.Resource.RedirectUri;
private static string _clientSecret = Properties.Resource.ClientSecret;
private string _authority = _aadInstance + _tenantId;
private string _scope = Properties.Resource.Scope;

public void ConfigureAuth(IAppBuilder app)
{
    //Set the authentication to cookies
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    //Create a new cookie
    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    //Set the openId connect authentication settings and call the WebPortal app in Azure
    app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        ClientId = _clientId,
        Authority = _authority,
        RedirectUri = _RedirectUri,
        PostLogoutRedirectUri = _RedirectUri,
        ClientSecret = _clientSecret,
        UseTokenLifetime = false,
        SaveTokens = true,
        RedeemCode = true,
        Scope = _scope,
        ResponseType = OpenIdConnectResponseType.Code,
        Notifications = new OpenIdConnectAuthenticationNotifications()
        {
            AuthenticationFailed = (context) =>
            {
                return Task.FromResult(0);
            }
        }
    });

    app.UseStageMarker(PipelineStage.Authenticate);
}

Web API - Program.cs

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(options =>{options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultChallengeScheme = "oidc";}).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme).AddOpenIdConnect(openIdOptions =>{openIdOptions.ClientId = "7221484D-1550-4087-840D-7170BC566B93";openIdOptions.Authority = "https://login.microsoftonline.com/4c2ecc82-c268-467a-bb63-0e92247d5fab";openIdOptions.ResponseType = OpenIdConnectResponseType.Code;openIdOptions.GetClaimsFromUserInfoEndpoint = false;openIdOptions.CallbackPath = "/signin-oidc";openIdOptions.SaveTokens = true;openIdOptions.ClientSecret = "****";});

builder.Services.AddControllers();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbucklebuilder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();
var app = builder.Build();

// Configure the HTTP request pipeline.if (app.Environment.IsDevelopment()){app.UseSwagger();app.UseSwaggerUI();}
app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

Web API 控制器代码

[Authorize]
[HttpGet("GetRoleInfo")]
public async Task<IActionResult> GetRoleInfo()
{
    try
    {
        string userId = GetAzureUserId();

        List<Role> roles = await GetRoles();
        List<AdminRole> adminRoles = await GetAdminRoles();
        List<BusinessUser> businessUsers = await GetBusinessUsers();
        List<ApplicationUser> applicationUsers = await GetApplicationUsers();
        List<Application> applications = await GetApplications();

        var roleAdminModel = PopulateRoleInfo(userId, roles, adminRoles,   
        businessUsers,applicationUsers, applications);

        return Ok(roleAdminModel);

    }
    catch (Exception ex)
    {
        return StatusCode((int)HttpStatusCode.InternalServerError, ex.Message);
    }
}

错误信息(翻译后)

处理请求时发生未处理的异常。InvalidOperationException: 未指定authenticationScheme,且未找到DefaultChallengeScheme。可通过AddAuthentication(string defaultScheme)或AddAuthentication(Action configureOptions)设置默认方案。


解决方案

1. 修改Web API的认证配置为JWT Bearer

Web API作为资源服务,应验证Web App传递的Azure AD Access Token,而非使用Cookie+OIDC认证。修改Program.cs中的认证配置:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// 添加JWT Bearer认证,配置Azure AD参数
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

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

app.Run();

同时在appsettings.json中添加Azure AD配置:

"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "TenantId": "4c2ecc82-c268-467a-bb63-0e92247d5fab",
  "ClientId": "7221484D-1550-4087-840D-7170BC566B93"
}

2. 确保Web App调用Web API时传递Access Token

在Web App中调用Web API时,需从认证上下文获取Access Token并在请求头中携带:

// 从OIDC保存的令牌中获取Access Token
var accessToken = await HttpContext.GetTokenAsync("access_token");

// 创建HttpClient并添加Authorization头
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await client.GetAsync("https://your-web-api-url/api/controller/GetRoleInfo");

3. 验证Azure AD应用注册配置

  • 确认Web App的应用注册已添加对Web API应用的委托权限,并完成管理员同意。
  • 确认Web API的应用注册已暴露对应的API范围,且Web App已将该范围添加到_scope变量中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:55:57