如何用非对称加密保护无登录的.NET Core 6 Web API?
.NET Core 6.0 Web API 无登录式客户端密钥认证实现方案
一、实现步骤
1. 配置客户端密钥
在appsettings.json中存储每个客户端的唯一密钥,示例:
"ApiKeys": { "Client001": "K2xL9zQpR4tY7wE2rT5yU8iO1aS3dF6gH0jK", "Client002": "M3nB6vC8xZ0cV2bN5mK7lJ9kH1gF3dS5aD8s", "Client003": "P1oI9uY8tR7eW6qA5sD4fG3hJ2kL1zX0cV" }
2. 编写自定义认证处理器
继承AuthenticationHandler<AuthenticationSchemeOptions>,实现从请求头提取密钥并校验的逻辑:
public class ApiKeyAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions> { private const string ApiKeyHeader = "X-API-KEY"; private readonly IConfiguration _config; public ApiKeyAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IConfiguration config) : base(options, logger, encoder, clock) { _config = config; } protected override Task<AuthenticateResult> HandleAuthenticateAsync() { // 检查请求头是否包含密钥 if (!Request.Headers.TryGetValue(ApiKeyHeader, out var headerValues)) return Task.FromResult(AuthenticateResult.Fail("未提供API密钥")); var providedKey = headerValues.FirstOrDefault(); if (string.IsNullOrWhiteSpace(providedKey)) return Task.FromResult(AuthenticateResult.Fail("API密钥为空")); // 校验密钥有效性 var validKeys = _config.GetSection("ApiKeys").GetChildren().Select(k => k.Value).ToList(); if (!validKeys.Contains(providedKey)) return Task.FromResult(AuthenticateResult.Fail("无效的API密钥")); // 生成认证票据 var clientName = _config.GetSection("ApiKeys") .GetChildren().First(k => k.Value == providedKey).Key; var claims = new List<Claim> { new Claim(ClaimTypes.Name, clientName) }; var identity = new ClaimsIdentity(claims, Scheme.Name); var principal = new ClaimsPrincipal(identity); var ticket = new AuthenticationTicket(principal, Scheme.Name); return Task.FromResult(AuthenticateResult.Success(ticket)); } }
3. 注册认证服务
在Program.cs中配置认证和授权服务:
builder.Services.AddAuthentication("ApiKeyScheme") .AddScheme<AuthenticationSchemeOptions, ApiKeyAuthHandler>("ApiKeyScheme", _ => { }); builder.Services.AddAuthorization();
4. 启用认证中间件
在Program.cs的请求管道中添加:
app.UseAuthentication(); app.UseAuthorization();
5. 保护API端点
在需要保护的控制器或Action上添加授权特性:
[ApiController] [Route("api/[controller]")] [Authorize(AuthenticationSchemes = "ApiKeyScheme")] public class DataController : ControllerBase { // 接口逻辑... }
二、密钥匹配方案的安全性分析
这种静态密钥匹配方案在合规使用的前提下是安全的,但有几个关键前提和局限性:
- 必须强制HTTPS:HTTP传输会导致密钥明文泄露,完全失去安全意义,生产环境必须配置SSL证书。
- 密钥存储要加密:不要把密钥明文写在
appsettings.json里,生产环境建议用Azure Key Vault、AWS Secrets Manager这类机密管理服务,或者通过环境变量注入密钥。 - 要做密钥轮换:定期更换客户端密钥,避免密钥泄露后被长期滥用。
- 配合限流机制:加上AspNetCoreRateLimit这类限流中间件,防止攻击者暴力破解密钥。
- 局限性:静态密钥没有会话生命周期,一旦泄露必须立即更换;如果需要细粒度权限控制,要在密钥关联的客户端信息中添加权限声明,扩展认证逻辑。
内容的提问来源于stack exchange,提问作者DevSa
相关产品推荐
相关产品推荐

