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


    前言

    在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"
    }
    
    

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

    源码解析

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

  • 相关阅读:
    windows下配置mysql环境变量
    360Top奢侈品演示站
    CSS3性能体验
    使用jquery获取radio的值
    获取select 的 val 和 text [转引]
    PHP时间比较和时间差如何计算
    InnoDB和MyISAM的区别与选择
    大型网站技术架构学习摘要
    大型网站系统架构分析--转
    一步步构建大型网站架构-转
  • 原文地址:https://www.cnblogs.com/yyfh/p/11855862.html
Copyright © 2020-2023  润新知