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

如何记录未通过身份验证的ASP.NET Core WebAPI调用?

未认证/认证失败API调用的记录实现方案

因为ActionFilterAttribute的OnActionExecuting仅在认证通过后才会触发,未认证的请求根本走不到这个环节,所以得从更早的请求管道节点入手,以下是两种实用方案:

1. 自定义中间件(覆盖全场景)

中间件是请求进入ASP.NET Core管道的早期环节,能捕获所有到达服务器的请求,不管认证是否成功,适合记录所有未授权类请求(包括路由匹配失败、认证失败、权限不足等场景)。

实现步骤

  • 新建中间件类,比如UnauthorizedRequestLoggerMiddleware
  • 在InvokeAsync方法中先记录请求基础信息,再传递请求到下一个中间件
  • 后续检查响应状态码,针对401(未认证)或403(权限不足)的请求补全记录

示例代码:

public class UnauthorizedRequestLoggerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<UnauthorizedRequestLoggerMiddleware> _logger;

    public UnauthorizedRequestLoggerMiddleware(RequestDelegate next, ILogger<UnauthorizedRequestLoggerMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 提前记录请求核心信息
        var requestPath = context.Request.Path;
        var requestMethod = context.Request.Method;
        var clientIp = context.Connection.RemoteIpAddress?.ToString();

        // 允许后续环节重读请求体(如需记录参数)
        context.Request.EnableBuffering();

        // 传递请求到下一个中间件
        await _next(context);

        // 判定是否为未授权类响应
        if (context.Response.StatusCode == StatusCodes.Status401Unauthorized || 
            context.Response.StatusCode == StatusCodes.Status403Forbidden)
        {
            // 如需读取请求参数,可在此处读取context.Request.Body(记得重置流位置)
            _logger.LogWarning("未授权请求: 路径={Path}, 方法={Method}, 客户端IP={ClientIp}, 状态码={StatusCode}",
                requestPath, requestMethod, clientIp, context.Response.StatusCode);
        }
    }
}

// 扩展方法简化中间件注册
public static class UnauthorizedRequestLoggerMiddlewareExtensions
{
    public static IApplicationBuilder UseUnauthorizedRequestLogger(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<UnauthorizedRequestLoggerMiddleware>();
    }
}

注册中间件

在Program.cs(或旧版Startup.cs)中,将该中间件注册在认证中间件之前,确保能捕获所有请求:

var app = builder.Build();

// 放在UseAuthentication之前
app.UseUnauthorizedRequestLogger();

app.UseAuthentication();
app.UseAuthorization();

// 其他中间件配置...

2. 利用认证事件(聚焦认证环节)

如果只关注认证过程中的失败场景,可以直接在对应认证方案的事件中处理,比如JWT认证的OnAuthenticationFailed、Cookie认证的对应事件。

示例(以JWT认证为例):

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 常规JWT配置...
        options.Events = new JwtBearerEvents
        {
            // 处理JWT认证失败的情况(比如token无效、过期)
            OnAuthenticationFailed = context =>
            {
                var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();
                logger.LogError(context.Exception, "JWT认证失败: 路径={Path}, 方法={Method}",
                    context.HttpContext.Request.Path, context.HttpContext.Request.Method);
                return Task.CompletedTask;
            },
            // 处理认证通过但权限不足的情况
            OnChallenge = context =>
            {
                var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();
                logger.LogWarning("权限不足: 路径={Path}, 方法={Method}",
                    context.HttpContext.Request.Path, context.HttpContext.Request.Method);
                return Task.CompletedTask;
            }
        };
    });

这种方式更聚焦于认证环节的错误,适合只需要追踪认证相关失败的场景。

注意事项

  • 若要读取请求体内容,必须先调用context.Request.EnableBuffering(),否则后续环节无法再次读取请求体
  • 中间件方式覆盖范围更广,能捕获所有未到达Action的请求;认证事件方式仅覆盖认证流程内的失败情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:23:20