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

如何在ASP.NET Core网站特定API接口中基于Identity添加基本认证

实现基于Identity的基本认证(仅针对特定API)

要在不改动现有Identity功能的前提下,给指定API接口添加基于Identity用户数据库的基本认证,且限制特定角色访问,按以下步骤操作:

1. 自定义基本认证处理程序

创建一个继承自AuthenticationHandler<AuthenticationSchemeOptions>的类,直接复用Identity的用户验证逻辑:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;

public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    private readonly UserManager<IdentityUser> _userManager;

    public BasicAuthenticationHandler(
        IOptionsMonitor<AuthenticationSchemeOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock,
        UserManager<IdentityUser> userManager)
        : base(options, logger, encoder, clock)
    {
        _userManager = userManager;
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // 检查请求头是否包含Authorization
        if (!Request.Headers.ContainsKey("Authorization"))
            return AuthenticateResult.Fail("缺少Authorization请求头");

        try
        {
            // 解析Basic格式的认证凭证
            var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
            var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
            var credentials = Encoding.UTF8.GetString(credentialBytes).Split(':', 2);
            var username = credentials[0];
            var password = credentials[1];

            // 通过Identity的UserManager查找用户
            var user = await _userManager.FindByNameAsync(username);
            if (user == null)
                return AuthenticateResult.Fail("用户不存在");

            // 复用Identity的密码哈希验证逻辑
            if (!await _userManager.CheckPasswordAsync(user, password))
                return AuthenticateResult.Fail("密码错误");

            // 验证用户是否拥有指定角色
            var hasPermission = await _userManager.IsInRoleAsync(user, "ApiAllowedRole");
            if (!hasPermission)
                return AuthenticateResult.Fail("无API访问权限");

            // 生成认证票据
            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.Role, "ApiAllowedRole")
            };
            var identity = new ClaimsIdentity(claims, Scheme.Name);
            var principal = new ClaimsPrincipal(identity);
            var ticket = new AuthenticationTicket(principal, Scheme.Name);

            return AuthenticateResult.Success(ticket);
        }
        catch
        {
            return AuthenticateResult.Fail("认证处理失败");
        }
    }
}

2. 注册基本认证方案

在Program.cs中添加自定义认证方案,与原有Identity认证共存:

var builder = WebApplication.CreateBuilder(args);

// 保留原有Identity注册代码
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>() // 确保已启用角色支持
    .AddEntityFrameworkStores<ApplicationDbContext>();

// 注册自定义基本认证方案
builder.Services.AddAuthentication()
    .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>(
        "BasicAuth", // 方案标识,后续授权时需要指定
        options => { });

// 其他服务注册...

var app = builder.Build();

// 保留原有中间件顺序
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

// 认证中间件必须在授权中间件之前
app.UseAuthentication();
app.UseAuthorization();

// 路由配置...

app.Run();

3. 为指定API接口添加授权

在需要开放基本认证的API控制器或方法上,指定使用BasicAuth认证方案,并限制角色:

[ApiController]
[Route("api/external")]
public class ExternalApiController : ControllerBase
{
    // 仅允许拥有ApiAllowedRole角色的用户通过基本认证访问
    [Authorize(AuthenticationSchemes = "BasicAuth", Roles = "ApiAllowedRole")]
    [HttpGet("sensitive-data")]
    public IActionResult GetSensitiveData()
    {
        return Ok(new { Data = "仅授权用户可见的API数据" });
    }
}

关键说明

  • 完全复用Identity的用户数据库和密码哈希验证逻辑,无需额外维护用户信息
  • 原有网站的认证流程(如Cookie登录)不受影响,仅标记了指定授权特性的接口会触发基本认证
  • 提前给需要访问API的用户分配ApiAllowedRole角色(可通过后台管理或代码批量添加)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:52:09