前言
在ASP.Net Core2.X調用的CreateWebHostBuilder和3.X的主要區別在於WebHost的調用,CreateDefaultBuilder被Host替換,另外一個區別是對ConfigureWebHostDefaults()的調用;html
因爲新的主機生成器是通用主機生成器,所以咱們也須要知道默認Web主機配置默認配置了什麼.ConfigureWebHostDefaults
爲咱們默認作了哪些配置?咱們一塊兒來看看他爲咱們默認配置的HostFiltering,HostFilteringMiddleware,其實他作的是對請求主機頭的限制,也至關於一個請求主機頭白名單,標識着某些主機頭你能夠訪問,其他的你別訪問了我這邊未容許.json
如何使用
在這之初打算的是爲給你們分享一下如何配置;算了,咱們一塊兒開拓一下思惟看看他是如何作的這個中間件吧.順便再說說當咱們使用ASP.NET Core在咱們使用中如何配置,使用主機頭白名單app
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測試
在Configure方法中添加HostFiltering中間件ui
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.jsoncode
{ "AllowedHosts": "127.0.0.1" }
這樣就行了,那麼咱們再來測試一下看看.htm
源碼解析
/// <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中間件