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

        我们发布了一个应用程序,该应用程序运行在一个相当隐蔽的 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        MaxReqs/sec      2292.70     326.38    7095.61Latency       54.52ms     2.29ms   109.00msHTTP codes:1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput:   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        MaxReqs/sec      1496.73     287.61    4500.00Latency       83.52ms    15.73ms      0.86sHTTP codes:1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput:   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        MaxReqs/sec      1471.50     285.97    5090.86Latency       84.96ms    17.64ms      0.87sHTTP codes:1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput:   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        MaxReqs/sec      2118.76     444.32    6498.38Latency       59.03ms    14.41ms   576.00msLatency Distribution50%    57.00ms75%    59.96ms90%    70.00ms95%    75.00ms99%    90.81msHTTP codes:1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput:   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        MaxReqs/sec      1392.11     328.62    8995.50Latency       89.92ms    19.01ms      1.09sLatency Distribution50%    88.00ms75%    91.00ms90%    97.00ms95%   111.00ms99%   125.00msHTTP codes:1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput:   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        MaxReqs/sec      1284.89     311.66    4550.25Latency       97.31ms    21.58ms      1.22sLatency Distribution50%    95.00ms75%    99.00ms90%   108.00ms95%   119.00ms99%   150.00msHTTP codes:1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput:   467.73KB/s

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/488418.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qt 封装 调用 dll

这个目录下 &#xff0c;第一个收藏的这个 &#xff0c;可以用&#xff0c; 但是有几个地方要注意 第一.需要将dll的头文件添加到qt的文件夹里面 第二&#xff0c;需要在pro文件里面添加动态库路径 第三&#xff0c;如果调用dll失败&#xff0c;那么大概需要将dll文件放在e…

基于自注意力网络的SASRec

运用了自注意力网络&#xff08;self-attention network&#xff0c;SAN&#xff09;的序列推荐算法&#xff08;SASRec&#xff09;能以并行化的方式捕捉同一序列上不同时间步间的转移关系&#xff0c;最后通过加权求和的方式得出每个时间步的序列特征。 算法原理&#xff1a;…

从一个Bug谈前端响应拦截器的应用

一、问题场景 今天在开发商品管理系统时&#xff0c;遇到了一个有趣的问题&#xff1a;当添加重复的商品编号时&#xff0c;页面同时弹出了两条 "商品编号已存在" 错误提示&#xff1a; 这个问题暴露了前端错误处理机制的混乱&#xff0c;让我们从这个问题出发&…

【机器学习chp9】集成学习

一、集成学习的概念 1. 什么是集成学习 定义&#xff1a;集成学习是一种通过组合多个模型&#xff08;称为基学习器&#xff09;来提升整体系统性能的方法。优点&#xff1a; 单个模型性能可能已经优化到极限&#xff0c;难以进一步提高&#xff0c;集成学习通过少量额外工作…

复合机器人整体解决方案

复合机器人是一种集成移动机器人和协作机器人两项功能为一身的新型机器人&#xff0c;更符合人们想象中“脑、眼、手、脚”融合的机器人终极形态。复合机器人的整体解决方案通常涉及多个方面&#xff0c;包括机器人本体、控制系统、感知系统、执行系统以及周边配套设备等。以下…

SpringBoot【十】mybatis之xml映射文件>、<=等特殊符号写法!

一、前言&#x1f525; 环境说明&#xff1a;Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 在利用mybatis进行开发的时候&#xff0c;编写sql时可能少不了>、<等比较符号&#xff0c;但是在mapper映射文件中直接使用是不行的&#xff0c;会报错&#xff0…

Elasticsearch:使用阿里 infererence API 及 semantic text 进行向量搜索

在之前的文章 “Elasticsearch 开放推理 API 新增阿里云 AI 搜索支持”&#xff0c;它详细描述了如何使用 Elastic inference API 来针对阿里的密集向量模型&#xff0c;稀疏向量模型&#xff0c; 重新排名及 completion 进行展示。在那篇文章里&#xff0c;它使用了很多的英文…

windows下Qt5自动编译配置QtMqtt环境(11)

文章目录 [toc]1、概述2、准备1.1 下载源码1.2 配置环境1.3 解释原理 3、编译4、验证5、参考6、视频 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt网络编程 &#x1f448; 1、概述 Qt默认是不包含mqtt库的&#xff0c;如果需要使用到mqtt库就只能自己编译配…

关于OpenAI Sora上线!AI视频生成的新纪元

OpenAI Sora的上线无疑是人工智能领域的一个重要进展&#xff0c;它标志着AI技术在视频生成和编辑方面迈出了一大步。 引言 在人工智能的快速发展中&#xff0c;OpenAI的最新力作——Sora&#xff0c;标志着AI视频生成技术的一个新纪元。Sora的上线不仅是技术上的一次飞跃&am…

K8S对接ceph的RBD块存储

1 PG数量限制问题 1.1 原因分析 1.还是老样子&#xff0c;先创建存储池&#xff0c;在初始化为rbd。 [rootceph141~]# ceph osd pool create wenzhiyong-k8s 128 128 Error ERANGE: pg_num 128 size 3 for this pool would result in 295 cumulative PGs per OSD (2067 tot…

Windows11安装Isaac Lab

1.1 下载文件 将 Isaac Lab 仓库克隆到您的工作空间&#xff1a; git clone https://github.com/isaac-sim/IsaacLab.git 1.2 创建Isaac Sim符号链接 F:cd IsaacLab 官方文档里路径/有问题&#xff0c;改成\&#xff09;&#xff1a; # 打开IsaacLab目录cd IsaacLab# 使用…

NES游戏机项目制作笔记(未完成)

24年12月1日晚记——在网上找项目学习的时候发现一个有意思的项目&#xff0c;准备靠这个应用一些STM32的高级功能。值得提醒的是——目的在于学习不可贪杯&#xff0c;注意效率 01 根据项目需求分析 为确保充分考虑每一个细节&#xff0c;并且让自己高效的完成项目制作&#…

ElasticSearch - 理解doc Values与Inverted Index倒排索引

文章目录 概述倒排索引&#xff1a;从图书馆的索引卡片谈起倒排索引的工作原理 docValues&#xff1a;从数据库的列式存储说起docValues的工作原理 docValues与倒排索引的对比两者的联系&#xff1a;组合使用&#xff0c;优化搜索与分析 小结 概述 在使用 Elasticsearch 进行大…

前端H5移动端基础框架模板 :Vue3 + Vite5 + Pinia + Vant4 + Sass + 附源码

技术栈选用 Vue3 Vite5 Pinia Vant4 Sass 源码地址&#xff1a; git clone https://gitee.com/gaiya001/h5-APP.git1. 1.vite.config.js文件配置 ** import { defineConfig } from vite // 导入 Vite 的配置函数 import vue from vitejs/plugin-vue // 导入 Vue 插件 i…

游戏引擎学习第36天

仓库 :https://gitee.com/mrxiao_com/2d_game 回顾之前的内容 在这个程序中&#xff0c;目标是通过手动编写代码来从头开始制作一个完整的游戏。整个过程不使用任何库或现成的游戏引擎&#xff0c;这样做的目的是为了能够全面了解游戏执行的每一个细节。开发过程中&#xff0…

C++小碗菜之五:GDB调试工具

“程序员不是编写代码的人&#xff0c;而是调试错误的人。” – 约翰本尼斯&#xff08;John Bennet&#xff09; 目录 前言 在虚拟机中安装 GDB GDB调试的实战演练 创建示例代码 例子&#xff1a; 使用 GDB 调试 编译代码 启动 GDB 设置断点 运行程序 打印变量值 …

【软件测试面试题】测试理论/基础面试(持续更新)

Hi&#xff0c;大家好。最近很多朋友都在说今年的互联网行情不好&#xff0c;面试很难&#xff0c;不知道怎么复习&#xff0c;我最近总结了一份在软件测试面试中比较常见的测试理论/基础面试面试题合集&#xff0c;希望对大家有帮助。建议点赞收藏再阅读&#xff0c;防止丢失&…

(css)element中el-select下拉框整体样式修改

(css)element中el-select下拉框整体样式修改 重点代码&#xff08;颜色可行修改&#xff09; // 修改input默认值颜色 兼容其它主流浏览器 /deep/ input::-webkit-input-placeholder {color: rgba(255, 255, 255, 0.50); } /deep/ input::-moz-input-placeholder {color: rgba…

十一、容器化 vs 虚拟化-Docker

文章目录 前言一、Docker 介绍1. 简介2. 应用场景3. 特点4. Docker和虚拟机之间的区别5. 解决痛点1. 解决依赖兼容2. 解决操作系统环境差异3. 小结 二、Docker 架构三、工作流程五、Docker 核心组件及其工作机制1. Docker 客户端&#xff08;Docker Client&#xff09;2. Docke…

游戏引擎学习第38天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾上次的内容。 我们之前讨论了将精灵放在屏幕上&#xff0c;但颜色错误的问题。问题最终查明是因为使用了一个调整工具&#xff0c;导致文件的字节顺序发生了变化。重新运行“image magic”工具对一些大图像进行重新处理后&am…