一、介绍

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

二、使用

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

    public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); var hosts = new List<string>();
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,并判断是否返回错误信息,如果返回错误信息,就将错误信息写到报文体中
if (_options.IncludeFailureMessage)
{
context.Response.ContentLength = DefaultResponse.Length;
context.Response.ContentType = "text/html";
return context.Response.Body.WriteAsync(DefaultResponse, , DefaultResponse.Length);
}
return Task.CompletedTask;
} return _next(context);//委托 调用下一个中间件
} private IList<StringSegment> EnsureConfigured()
{
if (_allowAnyNonEmptyHost == true || _allowedHosts?.Count > )//判断配置的是不是允许为空
{
return _allowedHosts;
} var allowedHosts = new List<StringSegment>();
if (_options.AllowedHosts?.Count > && !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 == )//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状态码。

.Net Core 中间件之主机地址过滤(HostFiltering)源码解析的更多相关文章

  1. ASP.NET Core主机地址过滤HostFiltering

    前言 在ASP.Net Core2.X调用的CreateWebHostBuilder和3.X的主要区别在于WebHost的调用,CreateDefaultBuilder被Host替换,另一个区别是对C ...

  2. abp vnext2.0核心组件之.Net Core默认DI组件切换到AutoFac源码解析

    老版Abp对Castle的严重依赖在vnext中已经得到了解决,vnext中DI容器可以任意更换,为了实现这个功能,底层架构相较于老版abp,可以说是进行了高度重构.当然这得益于.Net Core的D ...

  3. 源码解析.Net中Host主机的构建过程

    前言 本篇文章着重讲一下在.Net中Host主机的构建过程,依旧延续之前文章的思路,着重讲解其源码,如果有不知道有哪些用法的同学可以点击这里,废话不多说,咱们直接进入正题 Host构建过程 下图是我自 ...

  4. .NET Core实战项目之CMS 第三章 入门篇-源码解析配置文件及依赖注入

    作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9998021.html 写在前面 上篇文章我给大家讲解了ASP.NET Core的概念及为什么使用它,接着 ...

  5. .Net Core 认证系统之Cookie认证源码解析

    接着上文.Net Core 认证系统源码解析,Cookie认证算是常用的认证模式,但是目前主流都是前后端分离,有点鸡肋但是,不考虑移动端的站点或者纯管理后台网站可以使用这种认证方式.注意:基于浏览器且 ...

  6. AspNetCore源码解析_1_CORS中间件

    概述 什么是跨域 在前后端分离开发方式中,跨域是我们经常会遇到的问题.所谓的跨域,就是处于安全考虑,A域名向B域名发出Ajax请求,浏览器会拒绝,抛出类似下图的错误. JSONP JSONP不是标准跨 ...

  7. AspNetCore3.1源码解析_2_Hsts中间件

    title: "AspNetCore3.1源码解析_2_Hsts中间件" date: 2020-03-16T12:40:46+08:00 draft: false --- 概述 在 ...

  8. 设置ZooKeeper服务器地址列表源码解析及扩展

    设置ZooKeeper服务器地址列表源码解析及扩展 ZooKeeper zooKeeper = new ZooKeeper("192.168.109.130:2181",SESSI ...

  9. redux 中间件 --- applyMiddleware 源码解析 + 中间件的实战

    前传  中间件的由来 redux的操作的过程,用户操作的时候,我们通过dispatch分发一个action,纯函数reducer检测到该操作,并根据action的type属性,进行相应的运算,返回st ...

随机推荐

  1. BFS总结

    能够用 BFS 解决的问题,一定不要用 DFS 去做! 因为用 Recursion 实现的 DFS 可能造成 StackOverflow! (NonRecursion 的 DFS 一来你不会写,二来面 ...

  2. Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

  3. Linux上搭建Hadoop集群

    本文将为初学者的搭建简单的伪分布式集群,将搭建一台虚拟机,用于学习Hadoop 工具:vm虚拟机,centOS7,jdk-8,Hadoop2.7,xftp,xshell 用户:在虚拟机中创建一个had ...

  4. Python Memo 赋值与ID (Assignment & id())

    利用Python内置函数id()找出内部地址,探讨赋值与内建地址. id()的官方解释:this is the address of the object in memory 那么 a =1 是什么意 ...

  5. 了解iOS消息推送一文就够:史上最全iOS Push技术详解

    本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...

  6. Javascript高级编程学习笔记(77)—— 表单(5)过滤输入

    在日常实践中,我们常常会需要用户按照某种规则输入数据 但是文本框在默认情况下缺少验证数据的手段,因此需要使用JS来完成此类过滤输入的操作 通过事件和DOM的结合手段就能够将普通的文本框转换为功能型控件 ...

  7. UnicodeDecodeError:utf-8codeccantdecodebyte0xb9inposition0:invalidstartbyte

    相信这个问题大家都会以为是编码的问题,当然原本我也以为是编码问题! 然后试了各种方案!都是以失败告终!     哈哈哈,后来解决了,原来真是闹了个大笑话............         这是因 ...

  8. 吴恩达机器学习笔记1-单变量线性回归(Linear Regression with One Variable)

    在监督学习中我们有一个数据集,这个数据集被称训练集.

  9. MyBatis 多表关联查询

    多表关联查询 一对多 单条SQL实现. //根据部门编号查询出部门和部门成员姓名public dept selectAll() thorws Excatipon; //接口的抽象方法 下面是对应接口的 ...

  10. MyBatis别名与util类技能了解

    1.别名 在java中String类型就是String类型,但是在MyBatis中可不会识别java中的类型,在MyBatis中String类型的别名是'string',小写的String,或者也可以 ...