首頁

目前文章總數:172 篇

  

最後更新:2025年 03月 22日

0088. IIS Web網站 Session 持久化指南:.NET Core 與 .NET Framework 的配置與差異

日期:2025年 03月 22日

標籤: Asp.NET Core Entity Framework Internet Information Service Windows

摘要:C# 學習筆記


解決問題:微軟的 .Net Core 與 .Net Framework 是各自如何在 Windows Server 上的 IIS 實現 Sesstion 持久化,並詳解配置流程
基本介紹:本篇分為 4 部分。
第一部分:二者差異與介紹
第二部分:.Net Framework 於 IIS 實現方式
第三部分:.Net Framework 啟用持久化 Session 流程
第四部分:.Net Core 於 IIS 實現方式






第一部分:二者差異與介紹

Step 1:差異 - 系統架構 & 效能 & 安全性

  ASP.NET (.NET Framework) ASP.NET Core
系統架構與平台 只能在 Windows 上運行 跨平台(Windows、Linux、macOS)
  依賴 IIS 獨立運行,不依賴 IIS
  強依賴於 System.Web.dll 輕量級
效能與資源使用 記憶體占用較大 記憶體占用更少
  預設引入功能多 按需要自行引入功能
  啟動時間較長 啟動時間較短
安全性 Forms Authentication Identity 系統
  手動配置 CORS 更好的 CORS 支援
    內建 CSRF 防護




Step 2:差異 - Session 配置 & 優劣

關於配置模式兩者有以下:

ASP.NET (.NET Framework) ASP.NET Core
InProc 分散式 Session
StateServer Redis 支援
SQLServer 模式 更靈活的 Session 配置


因此優缺點延伸說明如下:

  ASP.NET (.NET Framework) ASP.NET Core
優點 開箱即用 跨平台
  配置簡單 支援多種儲存方案
  適合小型應用 可自定義實現
    支援分散式
    可上雲服務
     
缺點 擴展性差(IIS綁定)  
  只能在 Windows 上運行  
  StateServer 模式效能較差  
  無法自定義儲存方式  


Asp.net Core 大大提升了擴展性,不再侷限於 Windows 作業系統

Step 3:補充 - Forms Authentication 與 Identity 差別

Forms Authentication (.NET Framework) Identity (.NET Core)
基本的身份驗證、角色管理 完整的用戶管理系統
僅提供驗證框架 支援第三方登入(Google、Facebook等)


表單驗證(Forms Authentication )實現的代碼

// 登入驗證
public ActionResult Login(string username, string password)
{
    if (IsValid(username, password))
    {
		// 關鍵:自行設定表單 Cookie
        FormsAuthentication.SetAuthCookie(username, false);
        return RedirectToAction("Index", "Home");
    }
    return View();
}


Identity 實現的代碼
Program.cs,初始化的地方依賴注入,整個 Asp.net Core Web 的 Cookie 都會自動實現

// 配置 Identity
services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();


在 Controller.cs 層實作
await _signInManager.PasswordSignInAsync() 這個方法會進行 Cookie 的加密處理,並且自動封裝
用戶識別碼、角色信息、安全戳記(Security Stamp)、聲明(Claims)等資料,不同於表單驗證,安全性提高並且部分功能自動化處理。

public class AccountController : Controller
{
    private readonly SignInManager<ApplicationUser> _signInManager;
    
    public AccountController(
        SignInManager<ApplicationUser> signInManager
    {
        _signInManager = signInManager;
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        
        if (ModelState.IsValid)
        {
            // 關鍵: PasswordSignInAsync 會自動產生加密的 Cookie 
            var result = await _signInManager.PasswordSignInAsync(
                model.Email,
                model.Password,
                model.RememberMe,
                lockoutOnFailure: true);
        }

        return View(model);
    }
}



第二部分:.Net Framework 於 IIS 實現持久化方式

Step 1:範例代碼 - 專案

建立一個 Asp.net MVC 傳統的 EntityFrameWork 專案




Step 2:範例代碼 - 範例代碼 - 後端

控制器的部分代碼如下:
用戶首次訪問會將 Guid 寫入到 Session 於 Server端中,若後續訪問則會用相同的 Session Data

public class HomeController : Controller
{
    public ActionResult Index()
    {
        if (Session["UserData"] == null)
        {
            Session["UserData"] = Guid.NewGuid().ToString();
            ViewBag.SessionId = Session["UserData"];
        }
        else
        {
            ViewBag.SessionId = Session["UserData"];
        }
        return View();              
    }

}



Step 3:範例代碼 - 範例代碼 - 前端

檢視的部分如下:
將 Session Data 做顯示:

<main>
    <section class="row" aria-labelledby="aspnetTitle">
        <h1 id="title">ASP.NET Session 確認</h1>
    </section>

    <div class="row">
        <h3>當前 Session ID: @ViewBag.SessionId</h3>
    </div>
</main>



Step 4:範例代碼 - Web.Config

部署後需要在 IIS 上設定以下 配置 ※在 內,我們採用 StateServer 模式

InProc 單機模式,IIS重啟時遺失,保存在 w3wp.exe 中
StateServer 遠端持久化模式,由一個遠端的伺服器管理 Session 數據
  <system.web>
    <!-- InProc 模式(伺服器重啟後 Session 消失)
    <sessionState mode="InProc" timeout="20" />-->

    <!-- 或使用 StateServer 模式(伺服器重啟後 Session 保持)-->
    <sessionState mode="StateServer" 
                  stateConnectionString="tcpip=127.0.0.1:42424" 
                  timeout="20"
    />
    
    <compilation targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2" />
  </system.web>



Step 5:完成配置 : Demo

這時開啟網站,並且嘗試 IIS 多次重啟回收,可以發現 Session 都會保存,因為採用了 StateServer 將 Session 保存於另個位置上。


第三部分:.Net Framework 啟用持久化 Session 流程

Step 1:多台 IIS 持久化

若要多台 IIS 持久化 Session,必定不會使用 127.0.0.1localhost 的配置方式
需要有一台機器 (必須是 Windows 機器),設定該機器的訪問位置, Web.config 調整範例如下:

  <system.web>
    <!-- InProc 模式(伺服器重啟後 Session 消失)
    <sessionState mode="InProc" timeout="20" />-->

    <!-- 或使用 StateServer 模式(伺服器重啟後 Session 保持)-->
    <sessionState mode="StateServer" 
                  stateConnectionString="tcpip=192.168.51.101:42424" 
                  timeout="20"
    />
    
    <compilation targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2" />
  </system.web>


但是配置完成後,會出現以下錯誤,這是因為遠端 192.168.51.101 機器需要進行設定


Step 2:StateServer 配置 - 開啟服務

遠端 IIS 的機器,確保 aspnet_state 服務有在運行。
可以開啟 Windows CMD 輸入以下檢查, 有 Listening 表示啟動中

netstat -ano | findstr 42424




Step 3:StateServer 配置 - 防火牆開啟

開啟防火牆,要進行輸入、輸出規則的新增


Step 4:StateServer 配置 - 防火牆輸入規則

輸入規則開啟 42424 TCP Port


Step 5:StateServer 配置 - 防火牆輸出規則

輸出規則開啟 42424 TCP Port


Step 6:StateServer 配置 - 開啟註冊碼

在 Windows 的執行/CMD 中輸入以下:

regedit


然後到此路徑下:

HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\aspnet_state\\Parameters


可以看到參數 AllowRemoteConnection 為 0 ,表示不允許遠端連線


Step 6:StateServer 配置 - 註冊碼參數編輯

將參數 AllowRemoteConnection 設為 1 ,表示允許遠端連線


Step 7:Demo成果

可以發現連接正常,並且可以正常 Session ,在多台 IIS 部署時,只要 StateServer 不重啟,永遠都會讓 Session 持久化
在傳統 Asp.NET 架構下,要快速 Session 持久化這是一種方案 ※常見其他做法還有 SQL Server、Redis


第四部分:.Net Core 於 IIS 實現方式

Step 1:Session 持久化

可參考此篇:0085. 分布式 Session 實戰:使用 Redis 解決部署期間的用戶會話遺失問題
使用 Redis 進行 Session 持久化,並且 Asp.Net Core 較靈活,不需要綁定某個作業系統,而屬於跨平台