ASP.NET Core 8自定义认证Handler重复日志原因及消除方法咨询
ASP.NET Core 8自定义认证Handler重复日志问题
问题背景
基于ASP.NET Core 8实现了自定义认证Handler,核心代码、配置、管道及控制器代码如下:
自定义认证Handler核心代码
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() { /**/ bool isValidToken = false; if (!isValidToken) { Logger.LogInformation($"invalid token: {token}"); return AuthenticateResult.Fail($"Not authorized token: {token}"); } /**/ }
Handler配置代码
builder.Services.AddAuthentication(o => { //o.DefaultScheme = SecretKeyAuthenticationHandler.SchemeName; }).AddScheme<SecretKeyAuthenticationOptions, SecretKeyAuthenticationHandler>( SecretKeyAuthenticationHandler.SchemeName, o => { o.TokenName = conf["AppSettings:TokenName"] ?? "X-Auth-Token"; });
应用管道构建代码
var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
控制器装饰代码
[ApiController] [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.SchemeName)] [Route("[controller]")] public class WeatherForecastController : ControllerBase { }
发起未认证GET请求时,出现重复日志:
invalid token: *** SecretKeyScheme was not authenticated. Failure message: Not authorized token: *** SecretKeyScheme was not authenticated. Failure message: Not authorized token: *** AuthenticationScheme: SecretKeyScheme was challenged.
其中invalid token: ***仅打印一次,确认HandleAuthenticateAsync()只执行了一次,调试源码发现第二次日志来自PolicyEvaluator。
原因分析
两条重复日志的触发逻辑不同:
- 第一条:自定义Handler返回
AuthenticateResult.Fail()时,ASP.NET Core认证框架自动记录Info级别的认证失败日志。 - 第二条:进入授权阶段后,
PolicyEvaluator会校验指定Scheme的认证状态,发现结果为失败后,再次输出相同的认证失败日志。
解决办法
方法1:调整日志级别过滤
在appsettings.json中将Microsoft.AspNetCore.Authentication类别的日志级别设为Warning或更高,过滤掉Info级别的框架自动日志:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "Microsoft.AspNetCore.Authentication": "Warning" } } }
方法2:修改Handler返回结果
在Handler中返回AuthenticateResult.NoResult()代替Fail(),避免框架输出认证失败日志,同时在HandleChallengeAsync中手动处理401响应:
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() { /**/ bool isValidToken = false; if (!isValidToken) { Logger.LogInformation($"invalid token: {token}"); // 返回NoResult,不触发框架的Fail日志 return AuthenticateResult.NoResult(); } /**/ } protected override async Task HandleChallengeAsync(AuthenticationProperties properties) { Response.StatusCode = StatusCodes.Status401Unauthorized; await Response.WriteAsync("Not authorized token"); }
方法3:自定义PolicyEvaluator(不推荐)
通过替换默认PolicyEvaluator禁用授权阶段的日志,但需要编写较多自定义代码,复杂度高,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者tschmit
相关产品推荐
相关产品推荐

