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

基于.NET Framework 4.8的ASP.NET Core 2.2 API Azure AD授权问题

ASP.NET Core 2.2(.NET Framework 4.8)迁移Azure AD授权解决方案

问题背景

我有一个托管在.NET Framework 4.8中的ASP.NET Core 2.2 API,采用该架构是为了直接引用传统.NET Framework构建的类库。当前API使用ADFS,现需迁移至Azure AD。已配置Swagger并可通过选择作用域完成Azure AD认证,但授权功能无法正常工作。由于Microsoft.AspNetCore包无法在.NET Framework 4.8上安装,无法在Configure()中使用app.UseAuthorization();且Microsoft.Identity.Web包要求.NET Core 3.0及以上版本,恳请协助实现Azure AD授权功能。

当前代码片段

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider)
{
    app.UseStaticFiles();
    app.UseAuthentication();

    if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

    AspNetCore.Serilog.DependencyInjection.UseIdentityLogging(app);
    app.UseLogging();
    app.UseExceptionHandling();
    app.UseMvc();
    app.UseSwagger();
    app.UseAzureSwaggerUi(_azureAdConfig);
    app.UseCors(policy =>
        policy.WithOrigins("https://localhost:60216", "https://localhost:60216")
            .AllowAnyMethod()
            .WithHeaders(HeaderNames.ContentType)
    );
    app.UseAuthentication();
    app.UseAuthorization();//not available
}

public void ConfigureServices(IServiceCollection services)
{
       //Azure ad
    services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
        .AddAzureAD(options => Configuration.Bind("AzureAd", options));

    services.AddAuthorization(auth =>
    {
        auth.AddPolicy("AzureAD", new AuthorizationPolicyBuilder()
            .AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme‌​)
            .RequireAuthenticatedUser().Build());
    });

    services.AddSingleton<IAuthorizationHandler, RequiredRoleAuthorisationHandler>();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddSwaggerOAuth2Authorization(_azureAdConfig);
    services.RegisterAuthorisationPolicies();
    ConfigureSwagger(services);
    ConfigureApplicationServices(services);
}

解决方案

方案1:全局添加授权过滤器替代中间件

ASP.NET Core 2.2中可通过Mvc全局过滤器实现授权逻辑,替代UseAuthorization()的作用:

services.AddMvc(options =>
{
    // 全局绑定AzureAD授权策略
    var azureAdPolicy = new AuthorizationPolicyBuilder()
        .AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme)
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(azureAdPolicy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

方案2:自定义授权中间件

如果需要更灵活的管道控制,可手动实现授权中间件:

public class AuthorizationMiddleware
{
    private readonly RequestDelegate _next;

    public AuthorizationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, IAuthorizationService authorizationService)
    {
        // 指定要验证的策略名称
        var policyName = "AzureAD";
        var authResult = await authorizationService.AuthorizeAsync(context.User, null, policyName);

        if (!authResult.Succeeded)
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            return;
        }

        await _next(context);
    }
}

// 在Configure()中注册中间件,放在UseAuthentication()之后、UseMvc()之前
app.UseMiddleware<AuthorizationMiddleware>();

代码调整注意事项

  1. 移除Configure()中无效的app.UseAuthorization()调用,避免编译错误
  2. 验证Azure AD配置参数(TenantId、ClientId等)是否通过Configuration.Bind("AzureAd", options)正确绑定
  3. 确保自定义授权处理器RequiredRoleAuthorisationHandler逻辑正确,示例实现如下:
public class RequiredRoleAuthorisationHandler : AuthorizationHandler<RoleRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirement requirement)
    {
        if (context.User.HasClaim(c => c.Type == ClaimTypes.Role && c.Value == requirement.RequiredRole))
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }
}

public class RoleRequirement : IAuthorizationRequirement
{
    public string RequiredRole { get; set; }

    public RoleRequirement(string role)
    {
        RequiredRole = role;
    }
}

授权验证

在控制器或Action上通过[Authorize(Policy = "AzureAD")]标记,或使用全局过滤器后,所有接口将自动应用授权策略。可通过Swagger携带Azure AD令牌调用接口,验证是否返回正确的403/200状态码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:55:27