前言 在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"
}
這樣就好了,那麼我們再來測試一下看看.
源碼解析
/// <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