LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

在 C# 中實現(xiàn)單點登錄(SSO)的方法

admin
2025年7月28日 10:44 本文熱度 625

前言

想象一下這樣的場景:

每天早上,你打開電腦,先登錄OA系統(tǒng)查看郵件,再登錄CRM系統(tǒng)查看客戶信息,接著登錄財務系統(tǒng)審批報銷單...每個系統(tǒng)都要輸入用戶名密碼,而且為了防止安全風險,你還得為每個系統(tǒng)設置不同的復雜密碼。

這簡直是現(xiàn)代職場人的噩夢!

作為一名程序猿,我們不僅要解決自己的痛點,更要為用戶創(chuàng)造流暢的體驗。這就是單點登錄(Single Sign-On, SSO)誕生的意義——讓用戶只需登錄一次,就能訪問所有相互信任的系統(tǒng),告別密碼記憶的煩惱。

下面我們一起探索如何在 C# 中實現(xiàn)單點登錄(SSO)。

什么是單點登錄?

**單點登錄(SSO)**,顧名思義,就是 "一次登錄,處處通行"。

它是一種身份驗證機制,允許用戶使用一組憑據(jù)(如用戶名和密碼)登錄到多個應用程序或網(wǎng)站,而無需為每個應用程序單獨登錄。

SSO的核心思想可以用一個生活中的例子來理解:

假設你是一家大型公司的員工,公司有辦公大樓、健身房、餐廳和停車場。傳統(tǒng)方式下,你進入每個區(qū)域都需要出示不同的證件或刷卡。而有了SSO,就像公司給你發(fā)了一張萬能門禁卡,刷一次卡就能暢通無阻地進入所有區(qū)域。

從技術角度看,SSO主要解決了以下問題:

  1. 用戶體驗:減少用戶需要記憶的密碼數(shù)量,提高操作效率
  2. 安全管理:集中管理用戶身份,降低密碼泄露風險
  3. 系統(tǒng)集成:簡化不同系統(tǒng)間的身份驗證流程

SSO的實現(xiàn)方式

SSO的實現(xiàn)方式多種多樣,但核心思想都是集中認證,分散使用

下面是一些常見的實現(xiàn)方式:

  1. 基于Cookie的SSO(同域/子域場景)

    這是最簡單的SSO實現(xiàn)方式,適用于同一主域名下的不同子域名系統(tǒng)(如a.baidu.com和b.baidu.com)。

    原理是將認證信息存儲在父域名的 Cookie 中,子域名可以自動繼承父域名的 Cookie。

  2. 基于認證中心的SSO(跨域場景)

    對于完全不同的域名(如a.com和b.com),Cookie無法共享,這時就需要引入獨立的認證中心。

    常見的實現(xiàn)方案有CAS、OAuth2.0、OIDC和SAML等。

    以 CAS(Central Authentication Service) 為例,其流程大概如下:

    1. 用戶訪問a.com,a.com發(fā)現(xiàn)用戶未登錄,重定向到認證中心(sso.com)
    2. 用戶在sso.com完成認證,認證中心生成臨時票據(jù)(ST)
    3. 認證中心重定向回a.com并攜帶ST
    4. a.com后臺向認證中心驗證ST的有效性
    5. 驗證通過后,a.com建立本地會話
  3. 基于Token的SSO(現(xiàn)代Web應用)

    對于前后端分離的現(xiàn)代Web應用,常用JWT(JSON Web Token)實現(xiàn)SSO。

    認證中心頒發(fā) Token 后,前端將 Token 存儲在 LocalStorage 中,每次請求攜帶 Token,各子系統(tǒng)通過驗證 Token 確認用戶身份。

單點登錄實現(xiàn)例子

1. 創(chuàng)建解決方案和項目

打開VS2022,新建空白解決方案"SSODemo",然后添加三個ASP.NET Core Web應用項目:

  • SSO.Auth (認證中心)
  • SSO.AppA (子系統(tǒng)A)
  • SSO.AppB (子系統(tǒng)B)

2. 認證中心實現(xiàn)

在SSO.Auth項目中,添加LoginController:

[Route("auth")]
public class LoginController : Controller
{
    private static Dictionary<stringstring> _tickets = new Dictionary<stringstring>();
    
    [HttpGet("login")]
    public IActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
    
    [HttpPost("login")]
    public IActionResult Login(string username, string password, string returnUrl)
    {
        // 簡單模擬用戶驗證
        if(username == "admin" && password == "123456")
        {
            // 生成臨時票據(jù)(ST)
            var st = Guid.NewGuid().ToString();
            _tickets[st] = username;
            
            // 重定向回子系統(tǒng),攜帶ST
            return Redirect($"{returnUrl}?st={st}");
        }
        
        ViewBag.Error = "用戶名或密碼錯誤";
        return View();
    }
    
    [HttpGet("validate")]
    public IActionResult Validate(string st, string service)
    {
        if(_tickets.TryGetValue(st, out var username))
        {
            _tickets.Remove(st); // ST一次性使用
            return Ok(new { username });
        }
        return Unauthorized();
    }
}

3. 子系統(tǒng)實現(xiàn)

在SSO.AppA和SSO.AppB中,添加HomeController:

public class HomeController : Controller
{
    [HttpGet]
    public IActionResult Index()
    {
        // 檢查本地會話
        if(HttpContext.Session.GetString("username") != null)
        {
            ViewBag.Username = HttpContext.Session.GetString("username");
            return View();
        }
        
        // 未登錄,跳轉(zhuǎn)到認證中心
        var returnUrl = $"{Request.Scheme}://{Request.Host}";
        var ssoUrl = $"https://localhost:5001/auth/login?returnUrl={returnUrl}";
        return Redirect(ssoUrl);
    }
    
    [HttpGet("callback")]
    public async Task<IActionResult> Callback(string st)
    {
        // 驗證ST
        using(var client = new HttpClient())
        {
            var validateUrl = $"https://localhost:5001/auth/validate?st={st}&service=appA";
            var response = await client.GetAsync(validateUrl);
            
            if(response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                var result = JsonSerializer.Deserialize<dynamic>(content);
                string username = result.GetProperty("username").GetString();
                
                // 建立本地會話
                HttpContext.Session.SetString("username", username);
                return RedirectToAction("Index");
            }
        }
        
        return Unauthorized();
    }
    
    [HttpGet("logout")]
    public IActionResult Logout()
    {
        HttpContext.Session.Clear();
        return RedirectToAction("Index");
    }
}

4. 配置和運行

  1. 為每個項目設置不同的端口:

    • SSO.Auth: 5001
    • SSO.AppA: 5002
    • SSO.AppB: 5003
  2. 配置Session:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddSession(options => {
        options.IdleTimeout = TimeSpan.FromMinutes(30);
        options.Cookie.HttpOnly = true;
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ...
    app.UseSession();
    // ...
}
  1. 同時啟動三個項目,訪問AppA或AppB,都會被重定向到認證中心登錄。登錄成功后,再訪問另一個App,無需再次登錄。

總結(jié)

單點登錄在各種場景下都能大顯身手,我們經(jīng)常看到的一些接入微信、支付寶等第三方登錄的應用,本質(zhì)上是利用這些平臺作為認證中心的SSO流程。

作為 C# 程序員,我們可以利用 ASP.NET Core 強大的功能,相對輕松地實現(xiàn)各種 SSO 方案,無論是簡單的同域Cookie共享,還是復雜的跨域認證中心,.NET 都提供了完善的支持。

不過,在實現(xiàn) SSO 的時候,安全問題也是需要密切注意的,這里有一些建議:

  1. 通信時最好使用 HTTPS,防止憑證被竊取
  2. 票據(jù)尤其是臨時的票據(jù)要設置較短的有效期,一般不要超過5分鐘
  3. 使用 state 參數(shù)防止跨站請求偽造(CSRF攻擊)
  4. 有可能的情況下,進行敏感操作時最好進行二次驗證
  5. 實現(xiàn)全局注銷,確保所有系統(tǒng)會話都被清除

該文章在 2025/7/28 12:39:17 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結(jié)合碼頭的業(yè)務特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲高清一线视频在线播放 | 中文字幕乱码在线视频网站 | 亚洲午夜人成在线 | 日本精品中文字幕 | 亚洲精品国产精品乱码在线观看 | 亚洲小说区图片区另类春色 |