大型網站常將主站 www.xxx.com 與檔案下載站 file.xxx.com 分離部署,以分散流量。核心需求有二:
ASP.NET Forms 驗證底層以 Cookie 為憑證。若主站與子站共用相同 machineKey、forms name、path="/"、domain=".xxx.com",即可實現 Cookie 跨應用程式共享。
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Home/LogOn" defaultUrl="/" timeout="600"
slidingExpiration="true" name="File" path="/"
enableCrossAppRedirects="true" />
</authentication>
<httpCookies domain=".xxx.com" />
<machineKey validationKey="AAA977D304FB289C182E00C710A099C9F92986DC25AD69F8"
decryptionKey="AAA2B3F76A9359431E717CA8275EE72EEEDC70ED55152010"
validation="SHA1" />
</system.web>
<!-- 僅下載站需加入 -->
<system.webServer>
<handlers>
<add name="DownloadHandler" path="*.*" verb="*"
type="Web.Handler.Download" />
</handlers>
</system.webServer>
</configuration>
關鍵點說明:
name="File":兩站同名,Cookie 名稱一致。path="/":Cookie 作用路徑為根目錄,所有子應用程式可見。domain=".xxx.com":Cookie 釋放至頂級域名,子域名自動攜帶。machineKey:雙方完全相同,確保加解密演算法一致,Ticket 可互通。enableCrossAppRedirects="true":允許跨應用程式重導向登入頁。在下載站建立 Web.Handler.Download 類別,實作 IHttpHandler,掛載至 system.webServer/handlers(IIS 7+)或 system.web/httpHandlers(IIS 6)。
namespace Web.Handler
{
public class Download : IHttpHandler
{
public bool IsReusable { get { return true; } }
public void ProcessRequest(HttpContext context)
{
if (context.User.Identity.IsAuthenticated)
{
string filePath = context.Server.MapPath(context.Request.FilePath);
context.Response.ContentType = GetMimeType(filePath);
context.Response.TransmitFile(context.Request.FilePath);
}
else
{
context.Response.Write("您未登入!");
}
}
private string GetMimeType(string fileName)
{
// 簡易對應,實務建議用 MimeMapping 或註冊表查詢
string ext = System.IO.Path.GetExtension(fileName).ToLower();
switch (ext)
{
case ".pdf": return "application/pdf";
case ".zip": return "application/zip";
case ".jpg": case ".jpeg": return "image/jpeg";
case ".png": return "image/png";
default: return "application/octet-stream";
}
}
}
}
<add name="DownloadHandler" path="*.*" verb="*" type="Web.Handler.Download" />
path="*.*":攔截所有副檔名請求;若僅限圖片可改 *.jpg,*.png,*.gif。type:完整類別名稱(含命名空間),需置於 App_Code 或編譯組件中。system.webServer/handlers;經典模式或 IIS 6 置於 system.web/httpHandlers。Response.TransmitFile 直接由核心模式傳送檔案,不經 managed heap,記憶體佔用極低,適合大檔案。若需更精細控制(斷點續傳、速率限制),可改用 FileStream 分塊寫入 Response.OutputStream。
透過統一 machineKey、forms 設定與 httpCookies domain,輕鬆實現子域名單一登入。搭配 IHttpHandler 攔截所有檔案請求,在 ProcessRequest 中驗證 User.Identity.IsAuthenticated,即可構建安全、高效能的下載授權站。此架構擴充性強,後續可整合角色權限、下載次數統計、防盜鏈 Token 等進階功能。