ASP.NET Core Web Api自定义ApiKey过滤器云端无法读取IConfiguration值
问题:云端环境下ASP.NET Core 7.0过滤器无法读取IConfiguration中的ApiKey值
环境与架构
- OAuth应用:基于ASP.NET Core 7.0的Web API,负责用户登录、注册等功能
- 主应用:ASP.NET Core 3.1应用,托管Angular TS客户端并作为代理调用OAuth应用接口
ApiKey保护机制实现
过滤器注册
builder.Services.AddControllers(options => { options.Filters.Add(new ApiKeyFilter()); });
ApiKey特性定义
public class ApiKeyAttribute : ActionFilterAttribute { }
受保护接口示例
[ApiKey] public async Task<IActionResult> MyEndpoint() { ... }
ApiKeyFilter实现
public class ApiKeyFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { if (!context.ActionDescriptor.FilterDescriptors.Any(f => f.Filter is ApiKeyAttribute)) return; if (!HasValidApiKeyHeader(context.HttpContext)) context.Result = new UnauthorizedResult(); } public static bool HasValidApiKeyHeader(HttpContext httpContext) { Log.Debug("{0}.{1} called at {2} {3} with with headers: {4} ", nameof(ApiKeyFilter), nameof(HasValidApiKeyHeader), httpContext.Request.Method, httpContext.Request.GetDisplayUrl(), JsonSerializer.Serialize(httpContext.Request.Headers) ); if (httpContext.Request.Headers.TryGetValue("Api-Key", out StringValues apiKeyHeaderValues)) { IConfiguration config = (IConfiguration)httpContext.RequestServices.GetService(typeof(IConfiguration))!; string? apiKey = apiKeyHeaderValues.FirstOrDefault(); string keyFromConfig = config.GetValue<string>("ApiKey")!; bool isApiKeyValid = !string.IsNullOrWhiteSpace(apiKey) && apiKey == keyFromConfig; if (!isApiKeyValid) { Log.Warning("Invalid Api-Key ({0}) received in request {1}", apiKey, httpContext.Request.GetDisplayUrl()); return isApiKeyValid; } Log.Debug("Valid Api-Key found at: {0}", httpContext.Request.GetDisplayUrl()); return isApiKeyValid; } return false; } public void OnActionExecuted(ActionExecutedContext context) {} }
部署方式
应用以Docker镜像部署到AWS EC2实例的容器中,近期将OAuth应用从.NET Core 3.1升级到7.0后出现问题。
问题现象
- 所有受ApiKey过滤器保护的接口均返回401 Unauthorized(仅ApiKeyFilter会返回该结果)
- 过滤器中的日志未触发
- 无Microsoft.Information级别的请求路由日志
- 本地开发环境一切正常,未受保护的接口在云端也能正常调用
- 发送的ApiKey正确,REST客户端调用示例:
curl --location --request POST 'https://example.com/api/MyEndpoint' \ --header 'Api-Key: x0000000-xxx0-0000-0x00-x000000x00x0' \
排查更新
更新1:请求头验证
在ApiKeyFilter.OnActionExecuting()开头添加Console.WriteLine,输出显示请求头包含正确的Api-Key:
{ "Host": ["example.com"], "Content-Type": ["application/json"], "Request-Id": ["|13a33fec-4e61043c8419d40b.2."], "Content-Length": ["100"], "X-Forwarded-For": ["1.111.222.333"], "X-Forwarded-Proto": ["https"], "X-Forwarded-Port": ["443"], "X-Amzn-Trace-Id": ["Root=1-00aa111b-3cd4e5f67ghi8j901k23lm4n"], "Api-Key": ["x0000000-xxx0-0000-0x00-x000000x00x0"] }
更新2:配置读取问题
- 应用启动时打印的ApiKey配置值正确
- 过滤器中读取的ApiKey配置值为空或null,日志显示:
Request ApiKey is False received x0000000-xxx0-0000-0x00-x000000x00x0.
Config Api key parsed as
核心问题
为何本地环境能正常读取配置,而云端环境下过滤器无法获取IConfiguration中的ApiKey值?
内容的提问来源于stack exchange,提问作者Neophyte
相关产品推荐
相关产品推荐

