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

.NET 單一登入 (SSO) 實作全解析:Passport 集中驗證與跨域 Token 流轉機制

     編輯:ASP.NET 基礎

架構概覽

採用集中式 Passport 驗證:一個主站負責帳號驗證與 Token 簽發,多個分站(子系統)透過 Token 向主站換取使用者憑證,並建立本地 Session 減少後續網路往返。

SSO 架構圖

核心名詞定義

術語定義範例
主站集中驗證服務https://www.passport.com/
分站業務子系統https://www.a.com/、https://www.b.com/
憑證使用者身份資料(主站用 Cache,分站用 Session)UserId、Roles、DisplayName
Token跨域流通的唯一憑證,存於主站 Cookie(Domain=passport.com)Guid.NewGuid().ToString()

兩大登入流程

情境一:匿名使用者首次造訪分站 A

  1. 分站 A 偵測無本地 Session、無 Token → 302 導向主站登入頁(帶回跳網址)。
  2. 主站驗證帳密成功 → 寫入主站 Cache(Key=Token, Value=UserInfo, Expire=30min) → 簽發 Token Cookie(Domain=passport.com) → 302 導回分站 A(帶 Token 參數)。
  3. 分站 A 收到 Token → 呼叫主站 WebService TokenGetCredence(token) 取得 UserInfo → 寫入本地 Session → 允許存取。

情境二:已登入分站 A 的使用者造訪分站 B

  1. 瀏覽器自動攜帶主站 Cookie(Domain=passport.com)送至分站 B。
  2. 分站 B 讀取 Token → 呼叫主站 WebService 取得 UserInfo → 建立分站 B 本地 Session → 允許存取。
Token 流轉序列圖

關鍵技術實作細節

1. Token 簽發與跨域共享

// 主站登入成功後
string token = Guid.NewGuid().ToString("N").ToUpper();
var cookie = new HttpCookie("Token") { Domain = "passport.com" };
cookie.Values["Value"] = token;
Response.AppendCookie(cookie);

// 同時寫入主站 Cache(Token → UserInfo)
Cache.Insert("CERT_" + token, userInfo, null, 
    DateTime.Now.AddMinutes(30), TimeSpan.Zero);

分站如何取得主站 Cookie?
導向主站 gettoken.aspx,該頁讀取 Cookie 並以 QueryString 回傳給分站。

2. 主站憑證儲存(Cache + DataTable)

private static void EnsureCache()
{
    if (HttpContext.Current.Cache["CERT"] == null)
    {
        var dt = new DataTable();
        dt.Columns.Add("token", typeof(string)).Unique = true;
        dt.Columns.Add("info", typeof(object));
        dt.Columns.Add("timeout", typeof(DateTime));
        dt.PrimaryKey = new[] { dt.Columns["token"] };
        HttpContext.Current.Cache.Insert("CERT", dt, null,
            DateTime.MaxValue, TimeSpan.FromMinutes(60)); // 雙倍 Token 存活
    }
}

3. 分站基底頁面(AuthBase)統一驗證邏輯


public class AuthBase : Page
{
    protected override void OnLoad(EventArgs e)
    {
        if (Session["Token"] != null) { base.OnLoad(e); return; } // 本地憑證存在

        string token = Request.QueryString["Token"];
        if (!string.IsNullOrEmpty(token) && token != "$Token$")
        {
            var svc = new TokenService();
            object cred = svc.TokenGetCredence(token);
            if (cred != null)
            {
                Session["Token"] = cred; // 建立本地憑證
                base.OnLoad(e);
                return;
            }
        }
        // 導向主站登入或重新取 Token
        Response.Redirect(token == "$Token$" ? GetLoginUrl() : GetTokenUrl());
    }

    private string GetTokenUrl()
    {
        string url = Request.Url.AbsoluteUri;
        url += url.Contains("?") ? "&Token=$Token$" : "?Token=$Token$";
        return "https://www.passport.com/gettoken.aspx?BackUrl=" + Server.UrlEncode(url);
    }
    private string GetLoginUrl() { /* 類似,導向 userlogin.aspx */ }
}

所有需驗證的分站頁面僅需繼承 AuthBase 即可自動擁有 SSO 能力。

4. 登出與清理機制

  • 使用者主動登出:清除主站 Cache 對應 Token、清除當前分站 Session。
  • 全站登出(單一登出 SLO):主站提供清除所有分站 Session 的 WebService/HTTP 端點,登出時逐一呼叫。
  • 主站定時掃描 Cache 移除逾期 Token 記錄。

安全性與擴充建議

總結

本方案以「主站 Cache 存憑證、Cookie 跨域傳 Token、分站 Session 快取、基底頁面統一攔截」四大支柱,構建輕量級 .NET SSO 架構。若專案已邁向微服務或雲原生,建議直接導入 IdentityServer4 / Azure AD B2C 等符合 OAuth2/OIDC 標準的身分識別伺服器,以獲得更完整的聯盟身分、權限管理與稽核能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
面向建議
Token 傳輸全站強制 HTTPS,防止 Token 被竊聽重放。
Token 有效期短效(15-30 分鐘)+ Sliding Expiration,平衡安全與體驗。
跨域 Cookie若主站與分站非同根域,需 P3P 標頭或改用 OAuth2/OpenID Connect 標準流程。
高可用主站 Cache 改用 Redis Cluster / SQL Server Session State,支援多節點。
防 CSRFToken 簽發時綁定 User-Agent / IP 指紋,驗證時比對。