ASP.NET Core 託管和部署(二)【HTTP.sys】
ASP.NET Core 中的 HTTP.sys Web 伺服器實現
HTTP.sys
是僅在 Windows 上執行的適用於 ASP.NET Core 的 Web 伺服器
。 HTTP.sys
是 Kestrel
伺服器的替代選擇,提供了一些 Kestrel
不提供的功能。
重要
HTTP.sys 與ASP.NET Core 模組
不相容,無法與 IIS 或 IIS Express 結合使用。
HTTP.sys 支援以下功能:
Windows 身份驗證
- 埠共享
- 具有 SNI 的 HTTPS
- 基於 TLS 的 HTTP/2(Windows 10 或更高版本)
- 直接檔案傳輸
- 響應快取
WebSocket
(Windows 8 或更高版本)
受支援的 Windows 版本:
- Windows 7 或更高版本
- Windows Server 2008 R2 或更高版本
何時使用 HTTP.sys
HTTP.sys
對於以下情形的部署來說很有用:
-
需要將伺服器直接公開到 Internet 而不使用 IIS 的部署。
-
內部部署需要 Kestrel 中沒有的功能,如
Windows 身份驗證
。
HTTP.sys
是一項成熟的技術,可以抵禦多種攻擊,並提供可靠、安全、可伸縮的全功能 Web 伺服器。 IIS 本身作為 HTTP.sys 之上的 HTTP 偵聽器執行。
HTTP/2 支援
如果滿足以下基本要求,將為 ASP.NET Core 應用啟用 HTTP/2:
- Windows Server 2016/Windows 10 或更高版本
- 應用程式層協議協商 (ALPN) 連線
- TLS 1.2 或更高版本的連線
如果已建立 HTTP/2
連線,HttpRequest.Protocol
會報告 HTTP/2
。
預設情況下將啟用 HTTP/2
。 如果未建立 HTTP/2
連線,連線會回退到 HTTP/1.1
。 在 Windows 的未來版本中,將提供 HTTP/2 配置標誌,包括使用 HTTP.sys
禁用 HTTP/2
的功能。
對 Kerberos
進行核心模式身份驗證
HTTP.sys
通過 Kerberos
身份驗證協議委託給核心模式身份驗證。 Kerberos
和 HTTP.sys
不支援使用者模式身份驗證。 必須使用計算機帳戶來解密從 Active Directory
獲取的並由客戶端轉發到伺服器的 Kerberos
令牌/票證,以便對使用者進行身份驗證。 註冊主機的服務主體名稱 (SPN),而不是應用的使用者。
如何使用 HTTP.sys
配置 ASP.NET Core 應用以使用 HTTP.sys
-
使用
Microsoft.AspNetCore.App metapackage
(nuget.org)(ASP.NET Core 2.1 或更高版本)時,不需要專案檔案中的包引用。 未使用Microsoft.AspNetCore.App
元包時,向 Microsoft.AspNetCore.Server.HttpSys 新增包引用。 -
生成 Web 主機時呼叫
UseHttpSys
擴充套件方法,同時指定所需的HttpSysOptions
:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseHttpSys(options =>
{
// The following options are set to default values.
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
options.UrlPrefixes.Add("http://localhost:5000");
});
通過登錄檔設定處理其他 HTTP.sys
配置。
HTTP.sys 選項
Property | 說明 | 預設 |
---|---|---|
AllowSynchronousIO | 控制是否允許 HttpContext.Request.Body 和 HttpContext.Response.Body 的同步輸入/輸出。 | True |
Authentication.AllowAnonymous | 允許匿名請求。 | True |
Authentication.Schemes | 指定允許的身份驗證方案。 可能在處理偵聽器之前隨時修改。 通過 AuthenticationSchemes 列舉 Basic、Kerberos、Negotiate、None 和 NTLM 提供值。 | None |
EnableResponseCaching | 嘗試核心模式快取,響應合格的標頭。 該響應可能不包括 Set-Cookie、Vary 或 Pragma 標頭。 它必須包括屬性為 public 的 Cache-Control 標頭和 shared-max-age 或 max-age 值,或 Expires 標頭。 | True |
MaxAccepts | 最大併發接受數量。 | 5 × 環境。 |
ProcessorCount | ||
MaxConnections | 要接受的最大併發連線數。 使用 -1 實現無限。 通過 null 使用登錄檔的計算機範圍內的設定。 | null |
(無限制) | ||
MaxRequestBodySize | 請參閱 MaxRequestBodySize 部分。 | 30000000 個位元組 |
(~28.6 MB) | ||
RequestQueueLimit | 佇列中允許的最大請求數。 | 1000 |
ThrowWriteExceptions | 指示由於客戶端斷開連線而失敗的響應主體寫入應引發異常還是正常完成。 | False |
(正常完成) | ||
Timeouts | 公開 HTTP.sys TimeoutManager 配置,也可以在登錄檔中進行配置。 請訪問 API 連結詳細瞭解每個設定,包括預設值: | |
TimeoutManager.DrainEntityBody – HTTP 伺服器 API 對保持的連線消耗實體正文的時間上限。 | ||
TimeoutManager.EntityBody – 請求實體正文到達的時間上限。 | ||
TimeoutManager.HeaderWait – HTTP 伺服器 API 分析請求頭的時間上限。 | ||
TimeoutManager.IdleConnection – 空閒連線存在的時間上限。 | ||
TimeoutManager.MinSendBytesPerSecond – 響應的最小傳送速率。 | ||
TimeoutManager.RequestQueue – 請求在被應用選擇前在請求佇列中保留的時間上限。 | ||
UrlPrefixes | 指定要向 HTTP.sys 註冊的 UrlPrefixCollection。 最有用的是 UrlPrefixCollection.Add,它用於將字首新增到集合中。 可能在處理偵聽器之前隨時對這些設定進行修改。 |
MaxRequestBodySize
允許的請求正文的最大大小(以位元組計)。 當設定為 null
時,最大請求正文大小不受限制。 此限制不會影響升級後的連線,這始終不受限制。
在 ASP.NET Core MVC 應用中為單個 IActionResult
替代限制的推薦方法是在操作方法上使用 RequestSizeLimitAttribute
屬性:
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
如果在應用開始讀取請求後嘗試配置請求限制,則會引發異常。 IsReadOnly
屬性可用於指示 MaxRequestBodySize
屬性是否處於只讀狀態。只讀狀態意味著已經太遲了,無法配置限制。
如果應用應替代每個請求的 MaxRequestBodySize
,請使用 IHttpMaxRequestBodySizeFeature
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILogger<Startup> logger, IServer server)
{
app.Use(async (context, next) =>
{
context.Features.Get<IHttpMaxRequestBodySizeFeature>()
.MaxRequestBodySize = 10 * 1024;
var serverAddressesFeature =
app.ServerFeatures.Get<IServerAddressesFeature>();
var addresses = string.Join(", ", serverAddressesFeature?.Addresses);
logger.LogInformation($"Addresses: {addresses}");
await next.Invoke();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// Enable HTTPS Redirection Middleware when hosting the app securely.
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
-
如果使用的是 Visual Studio,請確保應用未經配置以執行 IIS 或 IIS Express。
在 Visual Studio 中,預設啟動配置檔案是針對
IIS Express
的。 若要作為控制檯應用執行該專案,請手動更改所選配置檔案,如以下螢幕截圖中所示:
配置 Windows Server
-
確定要為應用開啟的埠,並使用 Windows 防火牆或 PowerShell cmdlet 開啟防火牆埠,以允許流量到達
HTTP.sys
。 在部署到 Azure VM 時,在網路安全組
中開啟埠。 在以下命令和應用配置中,使用的是埠 443。 -
如果需要,獲取並安裝
X.509
證書。在 Windows 上,可使用
New-SelfSignedCertificate PowerShell cmdlet
建立自簽名證書。 有關不支援的示例,請參閱 UpdateIISExpressSSLForChrome.ps1。在伺服器的“本地計算機” > “個人”儲存中,安裝自簽名證書或 CA 簽名證書。
-
如果應用為
框架相關部署
,則安裝.NET Core
、.NET Framework
或兩者(如果應用是面向 .NET Framework 的 .NET Core 應用)。- .NET Core – 如果應用需要 .NET Core,請從 .NET Core 下載頁獲取並執行
.NET Core
執行時安裝程式。 請勿在伺服器上安裝完整 SDK。 - .NET Framework – 如果應用需要
.NET Framework
,請參閱.NET Framework 安裝指南
。 安裝所需的.NET Framework
。 可以從 .NET Core 下載頁獲取最新.NET Framework
的安裝程式。
如果應用是
獨立式部署
,應用在部署中包含執行時。 無需在伺服器上安裝任何框架。 - .NET Core – 如果應用需要 .NET Core,請從 .NET Core 下載頁獲取並執行
-
在應用中配置 URL 和埠。
預設情況下,ASP.NET Core 繫結到
http://localhost:5000
。 若要配置 URL 字首和埠,可採用以下方法:UseUrls
urls
命令列引數ASPNETCORE_URLS
環境變數UrlPrefixes
下面的程式碼示例展示瞭如何對埠 443 結合使用
UrlPrefixes
和伺服器的本地 IP 地址10.0.0.4
:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
// Server local IP address: 10.0.0.4
options.UrlPrefixes.Add("https://10.0.0.4:443");
});
UrlPrefixes
的一個優點是會為格式不正確的字首立即生成一條錯誤訊息。
UrlPrefixes
中的設定替代 UseUrls
/urls
/ASPNETCORE_URLS
設定。 因此,UseUrls
、urls
和 ASPNETCORE_URLS
環境變數的一個優點是在 Kestrel
和 HTTP.sys
之間切換變得更加容易。 有關更多資訊,請參見ASP.NET Core Web 主機
。
HTTP.sys 使用 HTTP 伺服器 API UrlPrefix 字串格式。
警告
不應使用頂級萬用字元繫結(http://*:80/
和http://+:80
)。 頂級萬用字元繫結會帶來應用安全漏洞。 此行為同時適用於強萬用字元和弱萬用字元。 請使用顯式主機名或 IP 地址,而不是萬用字元。 如果可控制整個父域(相對於易受攻擊的*.com
),子域萬用字元繫結(例如,*.mysub.com
)不會構成安全風險。 有關詳細資訊,請參閱 RFC 7230:第 5.4 節:主機。
-
在伺服器上預註冊 URL 字首。
用於配置 HTTP.sys 的內建工具為 netsh.exe。 netsh.exe 用於保留 URL 字首並分配 X.509 證書。 此工具需要管理員特權。
使用 netsh.exe 工具為應用註冊 URL:
netsh http add urlacl url=<URL> user=<USER>
<URL>
– 完全限定的統一資源定位器 (URL)。 不要使用萬用字元繫結。 請使用有效主機名或本地 IP 地址。 URL 必須包含尾部反斜槓。<USER>
– 指定使用者名稱或使用者組名稱。
在以下示例中,伺服器的本地 IP 地址是 10.0.0.4
:
netsh http add urlacl url=https://10.0.0.4:443/ user=Users
在 URL 註冊後,工具響應返回 URL reservation successfully added
。
若要刪除已註冊的 URL,請使用 delete urlacl
命令:
netsh http delete urlacl url=<URL>
-
在伺服器上註冊 X.509 證書。
使用 netsh.exe 工具為應用註冊證書:
netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
<IP>
– 指定繫結的本地 IP 地址。 不要使用萬用字元繫結。 請使用有效 IP 地址。<PORT>
– 指定繫結的埠。<THUMBPRINT>
– X.509 證書指紋。<GUID>
– 開發人員生成的表示應用的 GUID,以供參考。
為了便於參考,將 GUID 作為包標記儲存在應用中:
- 在 Visual Studio 中:
- 在“解決方案資源管理器”中,右鍵單擊應用,並選擇“屬性”,以開啟應用的專案屬性。
- 選擇“包”選項卡。
- 在“標記”欄位中輸入已建立的 GUID。
- 如果使用的不是 Visual Studio:
- 開啟應用的專案檔案。
- 使用已建立的 GUID,將
<PackageTags>
屬性新增到新的或現有的<PropertyGroup>
:
<PropertyGroup>
<PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
</PropertyGroup>
如下示例中:
- 伺服器的本地 IP 地址是
10.0.0.4
。 - 聯機隨機 GUID 生成器提供
appid
值。
netsh http add sslcert
ipport=10.0.0.4:443
certhash=b66ee04419d4ee37464ab8785ff02449980eae10
appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
在證書註冊後,工具響應返回 SSL Certificate successfully added
。
若要刪除證書註冊,請使用 delete sslcert
命令:
netsh http delete sslcert ipport=<IP>:<PORT>
netsh.exe 的參考文件:
- Netsh Commands for Hypertext Transfer Protocol (HTTP)(超文字傳輸協議 (HTTP) 的 Netsh 命令)
- UrlPrefix Strings(UrlPrefix 字串)
-
執行應用。
結合使用 HTTP(而不是 HTTPS)和大於 1024 的埠號繫結到 localhost,無需管理員許可權,即可執行應用。 對於其他配置(例如,使用本地 IP 地址或繫結到埠 443),必須有管理員許可權才能執行應用。
應用在伺服器的公共 IP 地址處響應。 此示例在 Internet 上的公共 IP 地址
104.214.79.47
處訪問伺服器。此示例使用的是開發證書。 在繞過瀏覽器的不受信任證書警告後,頁面安全載入。
代理伺服器和負載均衡器方案
如果應用由 HTTP.sys
託管並且與來自 Internet
或公司網路的請求進行互動,當在代理伺服器和負載均衡器後託管時,可能需要其他配置。 有關詳細資訊,請參閱配置 ASP.NET Core 以使用代理伺服器和負載均衡器
。
相關文章
- ASP.NET Core 託管和部署(一)【Kestrel】ASP.NET
- 翻譯 - ASP.NET Core 託管和部署 - 在 Linux 上使用 Nginx 託管 ASP.NET Core 網站ASP.NETLinuxNginx網站
- windows 服務中託管asp.net coreWindowsASP.NET
- ASP.NET Core託管執行Quartz.NET作業排程詳解ASP.NETquartz
- .NET 6學習筆記(3)——在Windows Service中託管ASP.NET Core並指定埠筆記WindowsASP.NET
- Linux透過 Docker 可以託管 .NET Core啦!LinuxDocker
- Asp.Net Core Blazor之容器部署ASP.NETBlazor
- 管中窺豹----.NET Core到.NET 8 託管堆的變遷
- 託管堆和垃圾回收(GC)GC
- asp.net core 2.1 部署 centos7ASP.NETCentOS
- Linux Docker 部署 ASP.NET Core應用LinuxDockerASP.NET
- 重學c#系列——c# 託管和非託管資源(三)C#
- ASP.NET Core - 依賴注入(二)ASP.NET依賴注入
- Jenkins + Docker + ASP.NET Core自動化部署JenkinsDockerASP.NET
- Kubernetes學習筆記(二):部署託管的Pod -- 存活探針、ReplicationController、ReplicaSet、DaemonSet、Job、CronJob筆記Controller
- Spring Boot專案微信雲託管入門部署Spring Boot
- Asp.Net Core WebAPI+PostgreSQL部署在Docker中ASP.NETWebAPISQLDocker
- 部署型CRM系統和託管型CRM系統的優缺點有哪些
- Kubernetes 實戰 —— 04. 副本機制和其他控制器:部署託管的 pod
- ASP.NET Core Authentication系列(二)實現認證、登入和登出ASP.NET
- 部署Dotnet Core應用到Kubernetes(二)
- Asp.Net中的Action和Func委託ASP.NET
- ASP.NET Core系列(二):建立第一個.Net Core 專案ASP.NET
- asp.net core 應用docke部署到centos7ASP.NETCentOS
- 重學c#系列——c# 託管和非託管資源與程式碼相關(四)C#
- ASP.NET Core 基於JWT的認證(二)ASP.NETJWT
- ASP.NET Core知識之RabbitMQ元件使用(二)ASP.NETMQ元件
- 伺服器託管是什麼意思,為什麼要託管?伺服器
- 藉助雲託管低成本部署企業微信應用
- 【Azure DevOps系列】使ASP.NET Core應用程式託管到Azure Web App ServicedevASP.NETWebAPP
- ASP.NET Core ----ASP.NET Core中使用Code FirstASP.NET
- ASP.NET 6.0 Core 遷移 ASP.NET Core 7.0ASP.NET
- 【譯】在 ASP.NET 和 ASP.NET Core 之間共享程式碼ASP.NET
- ASP.NET Core - 從Program和Startup開始ASP.NET
- 使用 ASP.NET Core 和 MongoDB 建立 Web APIASP.NETMongoDBWebAPI
- 伺服器託管和租用哪個更划算呢?伺服器
- 什麼是Asp.net Core?和 .net core有什麼區別?ASP.NET
- ASP.NET Core Web Api之JWT VS Session VS Cookie(二)ASP.NETWebAPIJWTSessionCookie