前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ASP.NET Core主机地址过滤HostFiltering

ASP.NET Core主机地址过滤HostFiltering

作者头像
HueiFeng
发布2020-02-24 16:01:51
1.9K0
发布2020-02-24 16:01:51
举报
文章被收录于专栏:HueiFeng技术专栏HueiFeng技术专栏

前言

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

由于新的主机生成器是通用主机生成器,因此我们也需要知道默认Web主机配置默认配置了什么.ConfigureWebHostDefaults为我们默认做了哪些配置?我们一起来看看他为我们默认配置的HostFiltering,HostFilteringMiddleware,其实他做的是对请求主机头的限制,也相当于一个请求主机头白名单,标识着某些主机头你可以访问,其余的你别访问了我这边未允许.

如何使用

在这之初打算的是为给大家分享一下如何配置;算了,我们一起开拓一下思维看看他是如何做的这个中间件吧.顺便再说说当我们使用ASP.NET Core在我们使用中如何配置,使用主机头白名单

代码语言:javascript
复制
 services.PostConfigure<HostFilteringOptions>(options =>
{
         if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
         {
         // "AllowedHosts": "localhost;127.0.0.1;[::1]"
         var hosts = Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
         // Fall back to "*" to disable.
         options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
  }
});

HostFilteringOptions

  • AllowedHosts允许访问的Host主机
  • AllowEmptyHosts是否允许请求头Host的值为空访问 默认为true
  • IncludeFailureMessage 返回错误信息,默认为true

在Configure方法中添加HostFiltering中间件

代码语言:javascript
复制
   public void Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder app, IWebHostEnvironment env)

        {
            app.UseHostFiltering();
            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello World! " + context.Request.Host);
            });
        }

appsettings.json

代码语言:javascript
复制
{
  "AllowedHosts": "127.0.0.1"
}

这样就好了,那么我们再来测试一下看看.

源码解析

代码语言:javascript
复制
        /// <summary>
        /// Processes requests
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public  Task Invoke(HttpContext context)
        {
            var allowedHosts = EnsureConfigured();//获取允许Host集合

            if (!CheckHost(context, allowedHosts))//判断当前Host是否在允许的Host集合中
            {
                return HostValidationFailed(context);//如果不在400
            }

            return _next(context);//继续走下一个中间件
        }


        private Task HostValidationFailed(HttpContext context)
        {
            context.Response.StatusCode = 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;
        }
        private IList<StringSegment> EnsureConfigured()
        {
            if (_allowAnyNonEmptyHost == true || _allowedHosts?.Count > 0)//判断配置是否为空
            {
                return _allowedHosts;
            }

            return Configure();
        }


        private IList<StringSegment> Configure()
        {
            var allowedHosts = new List<StringSegment>();
            if (_options.AllowedHosts?.Count > 0 && !TryProcessHosts(_options.AllowedHosts, allowedHosts))
            {
                _logger.WildcardDetected();
                _allowedHosts = allowedHosts;
                _allowAnyNonEmptyHost = true;
                return _allowedHosts;
            }

            if (allowedHosts.Count == 0)//至少一个Host
            {
                throw new InvalidOperationException("No allowed hosts were configured.");
            }

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.AllowedHosts(string.Join("; ", allowedHosts));
            }

            _allowedHosts = allowedHosts;
            return _allowedHosts;
        }

总结

这篇文章主要也许能给大家开阔一下思维,其实他的实现逻辑很简单,当我们请求带着Host头去访问的时候,通过该中间件判断该Host头是否在我们预先配置好的里面,如果在里面那么就继续请求下一个中间件,如果说不在那么不好意思400

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档