首页 > 编程语言 >使用 ASP.NET Core HttpLoggingMiddleware 记录 http 请求/响应

使用 ASP.NET Core HttpLoggingMiddleware 记录 http 请求/响应

时间:2024-12-07 11:33:29浏览次数:6  
标签:Core 5000 http ASP 100000 ms localhost 125

        我们发布了一个应用程序,该应用程序运行在一个相当隐蔽的 WAF 后面。他们向我们保证,他们的产品不会以任何方式干扰我们的应用程序。这是错误的。他们删除了我们几乎所有的“自定义”标头。为了“证明”这一点,我构建了一个中间件,用于存储我们收到和发送的所有唯一标头。然后我创建了一个转储所有标头的端点。

我创建了一个自定义中间件,LogHeadersMiddleware

public class LogHeadersMiddleware 
{
    private readonly RequestDelegate _next;
    private readonly ILogger<LogHeadersMiddleware> _logger;
    public static readonly List<string> RequestHeaders = new List<string>();
    public static readonly List<string> ResponseHeaders = new List<string>();

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

    public async Task Invoke(HttpContext context)
    {
        var uniqueRequestHeaders = context.Request.Headers
            .Where(x => RequestHeaders.All(r => r != x.Key))
            .Select(x => x.Key);
        RequestHeaders.AddRange(uniqueRequestHeaders);

        await _next.Invoke(context);
        var uniqueResponseHeaders = context.Response.Headers
            .Where(x => ResponseHeaders.All(r => r != x.Key))
            .Select(x => x.Key);
        ResponseHeaders.AddRange(uniqueResponseHeaders);
        
        // Log unique headers with ILogger
        ...
    }
}

然后我在中间件管道的早期就这样注册了它 

app.UseLogHeadersMiddleware();
app.Map("/show-headers", ShowHeaders);

因此,通过转到 /show-headers,您将看到我们的应用程序接收和发送的所有(唯一)标头的转储。 

新方法

微软现在已经在 ASP.NET Core 中添加了对 HTTP 日志记录的支持。
他们创建了自己的中间件,您可以像这样启用它:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Important to have it as early as possible
    app.UseHttpLogging(); 
    ...
    ...
    ...
}

如果您不进行任何自定义,则默认记录以下内容(请求和响应):

Request path
Status code
Querystring
Headers 

示例 - 默认实现

向 /user/login
主体发出 POST 请求

{
   "username": "josef",
   "password": "MyPassword"
}

Request 

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
      Request:
      Protocol: HTTP/1.1
      Method: POST
      Scheme: http
      PathBase:
      Path: /user/login
      QueryString:
      Accept: */*
      Connection: keep-alive
      Host: localhost:5000
      User-Agent: PostmanRuntime/7.28.1
      Accept-Encoding: gzip, deflate, br
      Content-Type: application/json
      Content-Length: 60 

Response

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
      Response:
      StatusCode: 200
      Content-Type: application/json; charset=utf-8
      Date: [Redacted]
      Server: [Redacted]
      Transfer-Encoding: chunked 

如您所见,使用默认配置,不会记录任何敏感信息。
让我们看看如何配置中间件来记录一些敏感数据。

示例 - 记录请求/响应主体

请求正文(危险)

这将记录请求标头和正文

services.AddHttpLogging(options =>
{
    options.LoggingFields = HttpLoggingFields.RequestPropertiesAndHeaders |
                            HttpLoggingFields.RequestBody;
});

Body体

{
    "username": "josef",
    "password": "MyPassword"
}

Request 

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
      Request:
      Protocol: HTTP/1.1
      Method: POST
      Scheme: http
      PathBase:
      Path: /user/login
      QueryString:
      Accept: */*
      Connection: keep-alive
      Host: localhost:5000
      User-Agent: PostmanRuntime/7.28.1
      Accept-Encoding: gzip, deflate, br
      Content-Type: application/json
      Content-Length: 60

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
      RequestBody: {
          "username": "josef",
          "password": "MyPassword"
      }

响应主体(危险)

这将记录响应标头和正文

services.AddHttpLogging(options =>
{
    options.LoggingFields = HttpLoggingFields.ResponsePropertiesAndHeaders |
                            HttpLoggingFields.ResponseBody;
});

Body

{
    "username": "josef",
    "password": "MyPassword"
}

Response

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
      Response:
      StatusCode: 200
      Content-Type: application/json; charset=utf-8

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
      ResponseBody: {"token":"very secret token"}

        如您所见,我们现在正在记录请求和响应主体。这在开发/调试期间可能非常有用,但您很可能永远不想在生产中这样做。通过盲目地记录请求/响应标头/主体,您可以(很可能)记录敏感数据。如果您觉得有必要记录标头和主体,请确保使用选择加入策略,如下所示:

services.AddHttpLogging(options =>
{
    options.LoggingFields = HttpLoggingFields.RequestPropertiesAndHeaders |
                            HttpLoggingFields.ResponsePropertiesAndHeaders;
    options.ResponseHeaders.Add("Non-Sensitive");
});

调用以下操作时...

[HttpGet("api/weather")]
public IActionResult Index()
{
    Response.Headers.Add("Sensitive", "034D4CD7-2FEB-4B19-86A3-CFCD5DB291AA");
    Response.Headers.Add("Non-Sensitive", "Hello");
    return new OkObjectResult(new
    {
        data = "Hello World"
    });

...仅会记录非敏感标头 

Request

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
Response:
StatusCode: 200
Content-Type: application/json; charset=utf-8
Date: [Redacted]
Server: [Redacted]
Transfer-Encoding: chunked
Sensitive: [Redacted]
Non-Sensitive: Hello

表现

考虑记录请求/响应主体时应用程序的性能会受到怎样的影响也很重要
。GET

没有 HttpLogging

❯ .\bombardier.exe -c 125 -n 100000 http://localhost:5000/api/weather
Bombarding http://localhost:5000/api/weather with 100000 request(s) using 125 connection(s)
 100000 / 100000 [==========================================] 100.00% 2287/s 43s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      2292.70     326.38    7095.61
  Latency       54.52ms     2.29ms   109.00ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   727.39KB/s

HttpLogging 的默认设置

❯ .\bombardier.exe -c 125 -n 100000 http://localhost:5000/api/weather
Bombarding http://localhost:5000/api/weather with 100000 request(s) using 125 connection(s)
 100000 / 100000 [==========================================] 100.00% 1492/s 1m6s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      1496.73     287.61    4500.00
  Latency       83.52ms    15.73ms      0.86s
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   474.86KB/s

已启用请求/响应主体日志记录

❯ .\bombardier.exe -c 125 -n 100000 http://localhost:5000/api/weather
Bombarding http://localhost:5000/api/weather with 100000 request(s) using 125 connection(s)
 100000 / 100000 [==========================================] 100.00% 1466/s 1m8s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      1471.50     285.97    5090.86
  Latency       84.96ms    17.64ms      0.87s
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   466.79KB/s

当打开HttpLogging时,吞吐量从 ~2300 req/s 变为 ~1500 req/
s.POST

没有 HttpLogging

❯ .\bombardier.exe -m POST http://localhost:5000/user/login -c 125 -n 100000 --duration 1s -l -H "Content-Type: application/json" -f "login.json"
Bombarding http://localhost:5000/user/login with 100000 request(s) using 125 connection(s)
 100000 / 100000 [==========================================] 100.00% 2112/s 47s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      2118.76     444.32    6498.38
  Latency       59.03ms    14.41ms   576.00ms
  Latency Distribution
     50%    57.00ms
     75%    59.96ms
     90%    70.00ms
     95%    75.00ms
     99%    90.81ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   771.02KB/s

HttpLogging 的默认设置

❯ .\bombardier.exe -m POST http://localhost:5000/user/login -c 125 -n 100000 --duration 1s -l -H "Content-Type: application/json" -f "login.json"
Bombarding http://localhost:5000/user/login with 100000 request(s) using 125 connection(s)
 100000 / 100000 [==========================================] 100.00% 1388/s 1m12s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      1392.11     328.62    8995.50
  Latency       89.92ms    19.01ms      1.09s
  Latency Distribution
     50%    88.00ms
     75%    91.00ms
     90%    97.00ms
     95%   111.00ms
     99%   125.00ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   506.18KB/s

已启用请求/响应主体日志记录

❯ .\bombardier.exe -m POST http://localhost:5000/user/login -c 125 -n 100000 --duration 1s -l -H "Content-Type: application/json" -f "login.json"
Bombarding http://localhost:5000/user/login with 100000 request(s) using 125 connection(s)
 100000 / 100000 [==========================================] 100.00% 1281/s 1m18s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      1284.89     311.66    4550.25
  Latency       97.31ms    21.58ms      1.22s
  Latency Distribution
     50%    95.00ms
     75%    99.00ms
     90%   108.00ms
     95%   119.00ms
     99%   150.00ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   467.73KB/s

我们可以看到,记录更多内容会对性能造成影响。记录请求/响应主体时,我们每秒会额外损失约 100 个请求。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。  

标签:Core,5000,http,ASP,100000,ms,localhost,125
From: https://blog.csdn.net/hefeng_aspnet/article/details/144264240

相关文章

  • websocket和http2有什么区别?http2能取代websocket吗?为什么?
    WebSocket和HTTP/2都是现代的网络协议,用于客户端和服务器之间的通信,但它们的设计目标和工作方式不同,因此各有优缺点。HTTP/2不能完全取代WebSocket。主要区别:连接类型:HTTP/2是基于请求-响应的模型,即使是服务器推送,客户端也需要先发起请求。WebSocket则建立一个持久连接,客户......
  • http和websocket能共用一个端口吗?为什么?
    是的,HTTP和WebSocket可以共用一个端口,通常是80端口(HTTP)或443端口(HTTPS)。这是因为WebSocket协议的设计就是为了能够与HTTP协同工作,并通过相同的端口进行通信。以下是原因:初始握手(Handshake):WebSocket连接的建立始于一个HTTP请求,称为“WebSocket握手”。客户端......
  • websocket和http有什么区别?
    WebSocket和HTTP是两种不同的网络协议,它们在前端开发中扮演着不同的角色,主要区别如下:1.连接方式:HTTP:基于请求-响应模型。客户端发送请求,服务器响应,然后连接关闭。每次交互都需要建立新的连接。这就像打电话,每次沟通都需要拨号和挂断。WebSocket:建立持久连接。客户端和服......
  • http跟https有什么区别?
    HTTP(HyperTextTransferProtocol)和HTTPS(HyperTextTransferProtocolSecure)都是用于在互联网上传输网页数据的协议,但它们之间有一个关键的区别:安全性。HTTP无加密:HTTP是明文传输协议,这意味着所有通过HTTP发送的数据都是未加密的。如果有人能够拦截这些数据包,他们就可以直接......
  • C#实现一个HttpClient集成通义千问-测试代码入手学习参数配置
    测试代码入手学习参数配置准备测试代码修改配置效果:修改消息内容测试流式输出设置流式输出的参数视频教程准备测试代码我们学习从测试代码开始,选择一个模型选择的大模型:通义千问2-VL-开源版-7B然后再API示例中,找到C#的示例代码测试代码:usingSystem.Net.Http.H......
  • 第67篇 .net core简述
    1.什么是.netcorenetcore是一个跨平台的高性能开源框架用具生成基于云连接的Internet的新的应用程序,可以建造web应用程序和服务,lot应用和移动后端,可以在Windows,macOS,和Linux上进行开发和部署,在asp.net4.x重新设计更改了体系结构形成了更精简的模块化框架1.1.netcore的特......
  • 自己手动创建https证书
    为什么要自己来创建?因为阿里云越来越抠门,以前一年20个免费https证书,每个证书可以用一年,现在每个证书只能用三个月了,但是我每个服务都需要一个https证书,根本不够用,学习都不够用,所以必须要自己创建https证书了如何创建首先安装openssl工具,我也不知道以前是怎么装的了,不懂问cha......
  • Azure Pipelines 监听文件改动时自动发布 .Net Core或者.Net Framework package到arti
    示例项目:https://dev.azure.com/guorj/_git/PackDemo因为一些需求,在代码有改动以后需要更新响应的package,以供其他项目来使用,但是每次手动打包比较麻烦,就想着给自动化了,可怜自动化出来这么久都没有用过。代码托管在微软的Azure上,所以使用的是AzurePipelines功能。懒得细写了,包......
  • Metasploit木马生成教程,零基础入门到精通,收藏这篇就够了
    0****1概述上次我们聊到了通过目标系统漏洞来获取目标的权限,其实我们除了可以通过目标系统的漏洞来获取meterpreter之外,还可以直接通过木马获取。msfvenom就是MSF中用来生成后门木马的模块,在目标机器上执行后门木马,然后在本地配置监听目标即可上线,攻击机即可获得me......
  • .netcore-实现列表数据导出PDF功能
    安装Nuget包QuestPDF核心代码publicstaticstringExportPdf(List<LogLoginListDto>list){TextStyletitleStyle=TextStyle.Default.FontSize(36).SemiBold().FontColor(Colors.Blue.Medium);stringfileName=string.Concat("LogLogin-",DateT......