博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.Net Core 中间件之主机地址过滤(HostFiltering)源码解析
阅读量:4708 次
发布时间:2019-06-10

本文共 3482 字,大约阅读时间需要 11 分钟。

原文:

一、介绍

  主机地址过滤中间件相当于一个白名单,标记哪些主机地址能访问接口。

二、使用

  新建WebAPI项目,修改Startup中的代码段如下所示。下面表示允许主机名为“localhost”的主机访问(不区分大小写),其他主机地址访问此项目的接口都会返回400错误。

    public void ConfigureServices(IServiceCollection services)        {            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);            var hosts = new List
(); hosts.Add("localhost");       //添加配置 services.AddHostFiltering(x => { x.AllowedHosts = hosts;//设置允许访问的Host 最少需要设置一个 x.AllowEmptyHosts = false;//是否允许请求头Host的值为空访问 默认值为true x.IncludeFailureMessage = true;//true表示返回错误信息,false表示返回空 默认为true }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); }        //使用中间件 app.UseHostFiltering(); app.UseMvc(); }

(正常访问)

上面为正常访问情况,为了模拟通过其他域名访问此接口,配置Host文件,在Host文件末尾加上下面一句话,通过地址https://baidu.com:5001/api/values来访问https://localhost:5001/api/values,这样做的目的是改变浏览器请求头中的Host的值为baidu.com。

localhost       baidu.com

(返回400)

由于请求头中没有填写Host信息,浏览器自动解析地址,将baidu.com作为Host的值,由于baidu.com不在我们定义的允许访问的主机地址中,所以返回400。但是我们可以伪造请求头,如下图:

(伪造请求头)

也可以直接将Host的值为空,因为上面配置的是运行为空的主机名访问。

三、源码解析

  既然是中间件,最重要的一个方法就是Invoke,因为这个方法会在每个请求中被调用。

    public Task Invoke(HttpContext context)        {            var allowedHosts = EnsureConfigured();//获取配置的允许访问的Host集合列表            if (!CheckHost(context, allowedHosts))//通过Http上下文,获取当前请求的Host,并判断是否在运行访问的Host列表中            {                context.Response.StatusCode = 400;//如果不在访问列表中,返回400,并判断是否返回错误信息,如果返回错误信息,就将错误信息写到报文体中                if (_options.IncludeFailureMessage)                {                    context.Response.ContentLength = DefaultResponse.Length;                    context.Response.ContentType = "text/html";                    return context.Response.Body.WriteAsync(DefaultResponse, 0, DefaultResponse.Length);                }                return Task.CompletedTask;            }            return _next(context);//委托 调用下一个中间件        }        private IList
EnsureConfigured() { if (_allowAnyNonEmptyHost == true || _allowedHosts?.Count > 0)//判断配置的是不是允许为空 { return _allowedHosts; } var allowedHosts = new List
(); if (_options.AllowedHosts?.Count > 0 && !TryProcessHosts(_options.AllowedHosts, allowedHosts)) { _logger.LogDebug("Wildcard detected, all requests with hosts will be allowed."); _allowedHosts = allowedHosts;//将配置的值赋给_alloweHosts _allowAnyNonEmptyHost = true; return _allowedHosts; } if (allowedHosts.Count == 0)//Host至少配置一个 { throw new InvalidOperationException("No allowed hosts were configured."); } if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Allowed hosts: {Hosts}", string.Join("; ", allowedHosts)); } _allowedHosts = allowedHosts; return _allowedHosts; }

这个中间件逻辑很简单,总体来说就是判断请求头中的Host的值是否在配置的列表中,如果在,就下面一个中间件继续处理。如果不在,就返回400状态码。

posted on
2019-05-27 09:09 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/10928943.html

你可能感兴趣的文章
mysql配置默认字符集为UTF8mb4
查看>>
WPF实现3D翻转的动画效果
查看>>
自定义圆环进度条
查看>>
UILayer
查看>>
复杂对象写入文件
查看>>
k8s-高级调度方式-二十一
查看>>
[HDU3555]Bomb
查看>>
基于dubbo的分布式系统(一)安装docker
查看>>
Recursion
查看>>
66. Plus One
查看>>
COMP30023 Computer Systems 2019
查看>>
CSS选择器分类
查看>>
Kali学习笔记39:SQL手工注入(1)
查看>>
C# MD5加密
查看>>
Codeforces Round #329 (Div. 2)D LCA+并查集路径压缩
查看>>
移动应用开发测试工具Bugtags集成和使用教程
查看>>
Java GC、新生代、老年代
查看>>
Liferay 6.2 改造系列之十一:默认关闭CDN动态资源
查看>>
多线程
查看>>
折线切割平面
查看>>