首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 跨伺服器檔案寫入實戰:共享資料夾、身分模擬與權限完整指南

     編輯:ASP.NET 基礎

應用場景

Web 伺服器 (Server A) 接收用戶上傳檔案,但因存儲空間、備份策略或架構隔離,需將檔案實際寫入獨立的檔案伺服器 (Server B)。最常見且成本最低的方案是利用 Windows 檔案共享 (SMB/CIFS) 配合身分模擬 (Impersonation)。

架構圖解

[Client] → [Web Server A (IIS)] → (SMB Share) → [File Server B]
                │
                └─ 需以具備 B 寫入權限的網域/本地帳號執行寫入動作

步驟 1:檔案伺服器 (B) 設定共享與帳號

  1. 建立資料夾 (例: D:\FileShare) → 右鍵「屬性」→「共用」→「進階共用」→ 勾選「共用此資料夾」→「權限」→ 新增帳號 DocShareUser → 給予「讀取/寫入」。
  2. 在 B 上建立本地使用者 DocShareUser,設定強式密碼,加入「Users」群組即可 (無需管理員權限)。
  3. 確認防火牆開放 TCP 445 (SMB) 及 139 端口。

步驟 2:Web 伺服器 (A) 建立同名帳號

在 A 上同樣建立 DocShareUser,**使用者名稱與密碼必須與 B 完全一致** (若為網域環境則直接使用網域帳號)。此為 NTLM 驗證自動匹配的關鍵。

步驟 3:IIS 虛擬目錄指向 UNC 路徑

  1. IIS 管理員 → 網站 → 右鍵「新增虛擬目錄」。
  2. 別名: FileShare;實體路徑: \\ServerB\FileShare (UNC 格式)。
  3. 「連線身分」→ 選「特定使用者」→ 輸入 DocShareUser 及密碼 → 「測試設定」皆綠燈。
  4. 「驗證」→ 啟用「Windows 驗證」,其餘停用。

IIS 虛擬目錄設定

步驟 4:建立信任關係 — 兩種方式擇一

方式一:Web.config 模擬帳號 (簡單但影響整站)

<system.web>
  <identity impersonate="true" userName="DocShareUser" password="YourPassword" />
</system.web>

⚠️ **副作用**:整個 ASP.NET 應用程式將以此身分執行,可能導致存取資料庫、登入系統等原本依賴 `ApplicationPoolIdentity` 的功能失效。另需額外授權 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files 給該帳號讀寫權限,否則編譯臨時檔案會失敗。

臨時檔案目錄授權

方式二:Global.asax 動態建立連線 (推薦,影響範圍最小)

protected void Application_Start()
{
    // 啟動時建立與 B 的 SMB 會話,憑證快取於 LSA,後續存取自動使用
    string cmd = @"net use \\ServerB\FileShare ""Password"" /user:""DocShareUser""";
    System.Diagnostics.Process.Start("cmd.exe", $"/c {cmd}").WaitForExit();
}

優點:不改變應用程式執行身分,僅建立 SMB 會話憑證;重啟 IIS 後需重新執行,可寫入 Windows 排程器或服務確保持久。

步驟 5:程式碼寫入檔案

string virtualPath = "~/FileShare/Uploads/"; // 虛擬目錄別名
string physicalPath = Server.MapPath(virtualPath); // 自動解析為 \\ServerB\FileShare\Uploads\
string savePath = Path.Combine(physicalPath, fileName);

using (FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
{
    await uploadedFile.InputStream.CopyToAsync(fs);
}

步驟 6:上傳大小限制調整

IIS 預設限制 4MB,修改 Web.config:

<system.web>
  <httpRuntime maxRequestLength="102400" executionTimeout="300" /> <!-- 100MB, 5分鐘 -->
</system.web>
<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="104857600" /> <!-- 100MB (bytes) -->
    </requestFiltering>
  </security>
</system.webServer>

常見坑與排查

現象可能原因解決
401/403 Unauthorized帳號密碼不一致、B 未授權該帳號、防火牆攔截逐項核對帳號、共用權限、NTFS 權限、防火牆 445 埠
「找不到網路路徑」UNC 路徑錯誤、DNS 解析失敗、SMB 服務未啟動用 `ping ServerB`、`net view \\ServerB` 測試連通性
寫入成功但檔案 0 bytesNTFS 權限僅有「列出資料夾/讀取資料」無「建立檔案/寫入資料」在 B 資料夾「安全性」頁籤給予 DocShareUser「修改」權限
ApplicationPoolIdentity 無法存取共享未建立信任關係 (步驟 4)執行 `net use` 或設定 `impersonate="true"`

總結

跨伺服器檔案寫入的核心在於 **身分一致性** 與 **最小權限原則**。推薦採用「虛擬目錄 + Global.asax net use」組合:設定簡單、不汙染應用程式身分、易於維護。若規模較大或需高可用,建議改用分散式檔案系統 (DFS)、對象存儲 (MinIO/S3) 或專用檔案服務 API。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved