一、介绍

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

二、使用

  新建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. 第46章:MongoDB-监控应用状态

    ① MongoDB监控  1 db.serverStatus() 查看实例运行状态(内存使用.锁.用户连接等信息) 通过比对前后快照进行性能分析 "connections" # 当 ...

  2. Android手机app的adb命令测试电量

    Android手机app电量测试 Android 5.0及以上的设备, 允许我们通过adb命令dump出电量使用统计信息 第一步:手机安装要测试的应用,打开手机开发者模式-USB模式,运行cmd.ex ...

  3. Jquery 在子页面上设置父页面元素的值

    使用情景:因为我父页面上有用art.dialog,而子页面上有项目中的框架弹出方法跟art.dialog冲突,不能使用art.dialog自带的方法传值, 所以只好用一种简单粗暴的方法来设置. var ...

  4. [转].NET Core、Xamarin、.NET Standard和.NET Framework四者之间的区别

    转至:https://segmentfault.com/a/1190000011539920 前段时日微软(Microsoft)正式发布了.NET Core 2.0,在很多开发社区中反响不错.但还是有 ...

  5. 与http协作的web服务器--代理、网关、隧道

    一台服务器可以搭建多个web站点 代理: 接受客户端发送的请求,转发给其他服务器,然后接受服务器的返回结果(响应)再返回给客户端.每次经过代理服务器,就会追加写入via首部信息. 按两种基准分类.一种 ...

  6. js获取复选框值

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. Python之路【第一篇】Linux常见命令语句

    查看当前目录:        pwd 查看文件具体大小: ls -l 返回上一级: cd.. 返回根目录:     cd / 创建一个隐藏文件:    vim .test 显示隐藏文件:      l ...

  8. MyBatis 源码分析系列文章合集

    1.简介 我从七月份开始阅读MyBatis源码,并在随后的40天内陆续更新了7篇文章.起初,我只是打算通过博客的形式进行分享.但在写作的过程中,发现要分析的代码太多,以至于文章篇幅特别大.在这7篇文章 ...

  9. ThreadLocal类的简单使用

    1.概述变量值的共享可以使用public 是static 变量的形式,所有的线程都使用同一个public static 变量. 如实现线程内的共享变量,jdk提供了ThreadLocal来解决这个问题 ...

  10. 第58节:Java中的图形界面编程-GUI

    欢迎到我的简书查看我的文集 前言: GUI是图形用户界面,在Java中,图形用户界面我们用GUI表示,而GUI的完整英文为: Graphical User Interface(图形用户接口), 所谓图 ...