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

ASP.NET Core实现仅指定API生效的Azure AD令牌校验自定义认证过滤器

方案说明

可以通过自定义授权过滤器实现该需求,你仅需要给指定的API接口打上对应的特性标记即可,其余接口不会受Azure AD令牌校验逻辑影响。


实现步骤

1. 调整现有配置

你之前写的服务注册代码无需修改,保留Startup.cs中的以下配置即可:

services.AddMicrosoftIdentityWebApiAuthentication(configuration, "AzureAd");

同时移除全局授权校验的相关配置,比如不要给全局控制器添加强制授权过滤器,也不要配置默认的全局授权策略。appsettings.json中的AzureAd配置也保持你当前的写法即可。

2. 编写自定义Azure AD授权过滤器

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

public class AzureAdTokenValidateAttribute : Attribute, IAsyncAuthorizationFilter
{
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        // 跳过标记了AllowAnonymous的接口
        var allowAnonymous = context.ActionDescriptor.EndpointMetadata
            .Any(m => m.GetType() == typeof(AllowAnonymousAttribute));
        if (allowAnonymous)
        {
            await Task.CompletedTask;
            return;
        }

        // 读取请求头的Bearer令牌
        var authHeader = context.HttpContext.Request.Headers.Authorization.FirstOrDefault();
        if (string.IsNullOrWhiteSpace(authHeader) || !authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = new UnauthorizedResult();
            await Task.CompletedTask;
            return;
        }
        var token = authHeader["Bearer ".Length..].Trim();

        try
        {
            // 读取你已经配置好的JWT校验参数
            var jwtOptions = context.HttpContext.RequestServices
                .GetRequiredService<IOptions<JwtBearerOptions>>().Value;
            var tokenHandler = new JwtSecurityTokenHandler();
            
            // 执行令牌有效性校验
            var claimsPrincipal = tokenHandler.ValidateToken(token, jwtOptions.TokenValidationParameters, out _);
            
            // 校验通过后将用户身份信息写入HttpContext
            context.HttpContext.User = claimsPrincipal;
        }
        catch
        {
            // 任何校验失败的情况直接返回401
            context.Result = new UnauthorizedResult();
            await Task.CompletedTask;
            return;
        }
        await Task.CompletedTask;
    }
}

3. 给指定接口绑定校验逻辑

仅需要在你要做Azure AD令牌校验的单个API上添加上述过滤器的特性即可,其余接口不会触发校验:

[ApiController]
[Route("api/[controller]")]
public class DemoController : ControllerBase
{
    // 仅该接口会触发Azure AD令牌校验
    [HttpGet("secure-data")]
    [AzureAdTokenValidate]
    public IActionResult GetSecureData()
    {
        // 校验通过后可以直接读取Azure AD返回的用户声明
        var userId = User.FindFirstValue("oid");
        return Ok(new { UserId = userId, Data = "敏感数据" });
    }

    // 该接口为公开接口,不会触发任何令牌校验
    [HttpGet("public-data")]
    public IActionResult GetPublicData()
    {
        return Ok("公开数据");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:27:05