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

.NET Core WebAPI中基于X-API-Key绕过OAuth认证的方案问询

.NET Core WebAPI 实现API Key绕过OAuth认证方案

实现步骤

1. 创建API Key认证处理逻辑

首先定义自定义的API Key认证方案和处理类,负责验证请求头中的X-API-Key:

using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using System.Text.Encodings.Web;

// API Key认证配置项
public class ApiKeyAuthOptions : AuthenticationSchemeOptions
{
    public const string SchemeName = "API-Key";
    public string HeaderName { get; set; } = "X-API-Key";
}

// API Key认证处理类
public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOptions>
{
    private readonly IApiKeyValidator _validator;

    public ApiKeyAuthHandler(
        IOptionsMonitor<ApiKeyAuthOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock,
        IApiKeyValidator validator)
        : base(options, logger, encoder, clock)
    {
        _validator = validator;
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // 检查请求头是否包含API Key
        if (!Request.Headers.TryGetValue(Options.HeaderName, out var headerValues))
        {
            // 无API Key,返回无结果,交由后续认证方案处理
            return AuthenticateResult.NoResult();
        }

        var apiKey = headerValues.FirstOrDefault();
        if (string.IsNullOrWhiteSpace(apiKey))
        {
            return AuthenticateResult.Fail("API Key不能为空");
        }

        // 验证API Key有效性(替换为你的实际验证逻辑)
        var user = await _validator.ValidateAsync(apiKey);
        if (user == null)
        {
            return AuthenticateResult.Fail("无效的API Key");
        }

        // 生成认证票据
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.Username)
            // 可添加其他用户权限Claim
        };

        var identity = new ClaimsIdentity(claims, Scheme.Name);
        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, Scheme.Name);

        return AuthenticateResult.Success(ticket);
    }
}

// API Key验证服务接口(需自行实现具体逻辑)
public interface IApiKeyValidator
{
    Task<User> ValidateAsync(string apiKey);
}

// 示例验证实现(实际应从数据库/配置中心读取有效API Key)
public class ApiKeyValidator : IApiKeyValidator
{
    public async Task<User> ValidateAsync(string apiKey)
    {
        // 示例:仅验证固定API Key,实际需替换为持久化存储验证
        if (apiKey.Equals("your-valid-api-key-xxx", StringComparison.OrdinalIgnoreCase))
        {
            return await Task.FromResult(new User { Id = 1, Username = "Api_User" });
        }
        return null;
    }
}

// 用户模型(根据你的业务调整)
public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
}

2. 配置Program.cs中的认证与授权

在现有OAuth/Cookie认证配置基础上,添加API Key认证方案,并调整授权策略支持多认证方式:

var builder = WebApplication.CreateBuilder(args);

// 注册API Key验证服务
builder.Services.AddScoped<IApiKeyValidator, ApiKeyValidator>();

// 配置认证服务
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
// 原有Cookie认证配置
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.Cookie.Name = "Your_Auth_Cookie";
    options.LoginPath = "/auth/login";
    // 其他Cookie配置...
})
// 原有OAuth认证配置
.AddOAuth("Your_OAuth_Scheme", options =>
{
    options.ClientId = builder.Configuration["OAuth:ClientId"];
    options.ClientSecret = builder.Configuration["OAuth:ClientSecret"];
    options.CallbackPath = "/auth/signin-oauth";
    // 原有OAuth事件处理
    options.Events = new OAuthEvents
    {
        OnCreatingTicket = context =>
        {
            OAuthHelper.Process(context);
            return Task.CompletedTask;
        }
    };
})
// 添加API Key认证方案
.AddScheme<ApiKeyAuthOptions, ApiKeyAuthHandler>(
    ApiKeyAuthOptions.SchemeName,
    options => { });

// 配置授权策略,允许API Key、Cookie、OAuth三种认证方式
builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .AddAuthenticationSchemes(
            ApiKeyAuthOptions.SchemeName,
            CookieAuthenticationDefaults.AuthenticationScheme,
            "Your_OAuth_Scheme")
        .Build();
});

builder.Services.AddControllers();

var app = builder.Build();

// 中间件顺序:认证在前,授权在后
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

关键逻辑说明

  • 当请求携带X-API-Key头时,ApiKeyAuthHandler会优先验证:
    • 验证通过则生成认证票据,认证成功,后续OAuth/Cookie中间件不会执行
    • 验证失败或无API Key时,返回NoResult,系统自动尝试后续的OAuth/Cookie认证流程
  • 授权策略中包含所有允许的认证方案,确保两种认证方式都能通过授权校验
  • 需根据业务实际实现IApiKeyValidator的验证逻辑,比如从数据库查询有效API Key关联的用户信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:06:23