如何为ASP.NET Core API控制器配置Bearer Token或API Key二选一认证
实现Bearer Token或API Key二选一的API认证
嘿,我刚好处理过一模一样的场景!要解决这个“二选一”的认证问题,核心是自定义一个授权策略,让ASP.NET Core明白只要满足其中一种认证方式就算通过,而不是默认的“同时满足”。下面一步步来:
1. 确保两种认证方案已正确配置
首先得确认你已经分别搞定了Bearer Token(比如JWT)和API Key的认证配置。假设你的API Key认证方案名称设为ApiKey,Bearer Token的默认方案名是Bearer(这个是ASP.NET Core JWT认证的默认值)。
举个配置示例(以.NET 6+的Program.cs为例):
// 配置JWT Bearer认证 builder.Services.AddAuthentication() .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { // 你的JWT验证参数,比如Issuer、Audience、SigningKey等 ValidateIssuer = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], // 其他配置... }; }) // 配置自定义API Key认证 .AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>("ApiKey", options => { // 这里填你的API Key配置,比如从哪个Header读取密钥,比如"X-Api-Key" options.ApiKeyHeaderName = "X-Api-Key"; });
2. 创建“二选一”的授权策略
接下来在Program.cs里添加一个自定义授权策略,指定允许的认证方案列表——这里的逻辑是只要通过其中一种方案的认证,就符合策略要求:
builder.Services.AddAuthorization(options => { options.AddPolicy("BearerOrApiKey", policy => { policy.RequireAuthenticatedUser(); // 把两种认证方案加进去,逻辑是OR关系 policy.AddAuthenticationSchemes("Bearer", "ApiKey"); }); });
3. 在控制器上应用这个策略
最后,把这个策略加到你的控制器(或者单个Action)上就行,替换掉默认的[Authorize]:
[Authorize(Policy = "BearerOrApiKey")] [ApiController] [Route("api/[controller]")] public class MyProtectedController : ControllerBase { // 你的API接口方法 [HttpGet("data")] public IActionResult GetProtectedData() { return Ok("这是需要认证才能访问的数据"); } }
原理说明
默认情况下,如果直接写[Authorize(AuthenticationSchemes = "Bearer,ApiKey")],ASP.NET Core会要求请求同时通过两种认证(逻辑AND)。但通过自定义策略的AddAuthenticationSchemes方法,我们把逻辑改成了OR——只要请求能通过其中一种认证方案的验证,就会被视为已授权。
测试验证
你可以分别用两种方式测试:
- 携带有效的Bearer Token请求,应该能正常返回数据
- 携带有效的API Key(比如在
X-Api-KeyHeader里)请求,也能正常访问 - 不带任何认证信息,会返回401 Unauthorized,符合预期
内容的提问来源于stack exchange,提问作者Jim Culverwell
相关产品推荐
相关产品推荐

