欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET Core主机地址过滤HostFiltering

程序员文章站 2022-07-02 08:45:49
前言 在ASP.Net Core2.X调用的CreateWebHostBuilder和3.X的主要区别在于WebHost的调用,CreateDefaultBuilder被Host替换,另一个区别是对ConfigureWebHostDefaults()的调用; 由于新的主机生成器是通用主机生成器,因此 ......

前言

在asp.net core2.x调用的createwebhostbuilder和3.x的主要区别在于webhost的调用,createdefaultbuilder被host替换,另一个区别是对configurewebhostdefaults()的调用;

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

如何使用

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

 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中间件

   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

{
  "allowedhosts": "127.0.0.1"
}

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

ASP.NET Core主机地址过滤HostFiltering

源码解析

        /// <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