SSO集成方案[隨筆]

来源:https://www.cnblogs.com/sy-ds/archive/2019/04/12/10696218.html
-Advertisement-
Play Games

看這個方案之前,先說明下為什麼要加入SSO,以防對大家產生不好的影響。我們產品使用傳統winform+db服務+Db存儲方式開發,一群老菜幫子開發,以傳統的datatble做數據傳遞,很多年了未有變化。 然後我來了,感覺我這個老菜幫子都受不了這種開發,然後下定決心,作了一些封裝,看起來有點像orm的 ...


看這個方案之前,先說明下為什麼要加入SSO,以防對大家產生不好的影響。我們產品使用傳統winform+db服務+Db存儲方式開發,一群老菜幫子開發,以傳統的datatble做數據傳遞,很多年了未有變化。

然後我來了,感覺我這個老菜幫子都受不了這種開發,然後下定決心,作了一些封裝,看起來有點像orm的感覺了,並決定加入嵌入bs頁面,美化界面,並補充winform在圖表功能方面的短板。

然後就造成了各BS模塊分別嵌入到CS不同的頁面中,並且各BS模塊中有涉及到對業務的操作。很危險!因為在網頁中可以直接打開各BS模塊視圖,無需登錄,無需驗證等。針對這種情況,SSO需求由此而來…

 

目標:

  1.BS模塊統一使用單點登錄,不能沒有限制就使用業務系統

  2.CS端嵌入BS時自動模擬SSO,實現可以免登錄使用頁面

 

下文SSO科普是複製不知道誰的博文的,具體是誰忘了,在此說明下

SSO整體流程圖:

 

 

 

SSO分為SSO-ServerSSO-Client兩個部分,SSO-Client可以是多個的,即各個需要單點登錄的client

SSO-Server

SSO-Server主要負責用戶登錄、註銷、為SSO-Client分配token、驗證token的工作。

SSO-Server分配Token

為SSO-Client分配Token的部分,在SSO-Client請求SSO受信頁面的時候,檢查SSO-Server是否登錄,如果沒有登錄則跳轉到SSO-Server的登錄頁面,如果已登錄,則執行分配Token的代碼,在分配完成以後將TokenID作為參數添加到returnUrl中,並跳轉到returnUrl。

當完成Token分配之後,頁面將帶有Token的參數跳轉到SSO-Client頁面,併在SSO-Client的Cookie中添加Token值,在以後的每次請求中,SSO-Client通過調用SSO-Server的服務來驗證Token的合法性。

ValidateToken用來驗證TokenID的合法性,KeepToken用來保持Token不會過期。

SSO-Client通過調用Validate驗證Token,並得到當前的登錄用戶信息。

SSO-Client

SSO-Client作為受信系統來存在的,它自己沒有認證系統,只能通過SSO-Server來完成用戶身份認證的工作。

當用戶請求SSO-Client的受保護資源時,SSO-Client會首先是否有TokenID,如果存在TokenID,則調用SSO-Server的介面來驗證這個TokenID是否合法;

驗證成功以後將會返回SSOToken的實例,裡面包含已登錄的用戶信息

 

科普後動手:

MVC.SSO.Service:MVC+Redis,MVC實現SSO-Server的所有功能,存儲和時效使用Redis管理,並使用Redis共用Session

主要代碼:

     /// <summary>
        /// 驗證是否包含該token,並返回信息
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        [HttpPost]
        public string ValidateToken(string key)
        {
            //var token = TokensManager.GetToken(key);

            try
            {
                MyToken token = new MyToken();
                token.ValidateToken = false;

                if (BoolValidateToken(key))
                {
                    token.User = redis.StringGet<USERS>(key);
                    token.ValidateToken = true;
                }

                return JsonConvert.SerializeObject(token);
            }
            catch (Exception ex)
            {
                throw new Exception("ValidateToken:" + ex.Message);
            }
        }


     /// <summary>
        /// 登錄
        /// </summary>
        /// <param name="name"></param>
        /// <param name="passWord"></param>
        /// <param name="backUrl"></param>
        /// <returns></returns>
        [HttpPost]
        public string Login(string name, string passWord, string backUrl)
        {
            try
            {
                MyMsg msg = new MyMsg();
                //tokenKey
                byte[] byts = System.Text.Encoding.Default.GetBytes(string.Format("{0},{1}", name, passWord));
                var key = Convert.ToBase64String(byts);
                //判斷是否TokenIds是否已存在該用戶,不存在則判斷登錄,添加到token
                if (!BoolValidateToken(key))
                {
                    var user = userBll.GetUser(name, passWord);
                    if (user == null)
                    {
                        msg.IsLogined = false;
                        msg.Msg = "用戶名或密碼錯誤,登錄失敗!";
                    }
                    msg.IsLogined = true;
                    //並添加到全局變數中
                    //TokensManager.AddToken(key, user);
                    Session["Token"] = key;
                    redis.StringSet<USERS>(key, user);
                }

                Session["Token"] = key;
                Response.Cookies.Add(new HttpCookie("cToken", key));
                if (!string.IsNullOrEmpty(backUrl))
                {
                    var url = backUrl + "?token=" + key;
                    //Response.Redirect(backUrl + "?token=" + key, true);//生成一個tokenId 發放到客戶端
                    msg.BackUrl = url;
                }
                msg.Msg = "歡迎您:" + name;
                return JsonConvert.SerializeObject(msg);
            }
            catch (Exception ex)
            {
                throw;
            }
        }

 

BS端MVC-Client集成方案

MVC集成SSO方式為添加過濾器,併在需要添加SSO驗證的控制器上添加上該過濾器

主要代碼:

public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);

            try
            {
                bool isLogined = false;//登錄標誌
                var cToken = filterContext.HttpContext.Request.Cookies["cToken"];
                var token = filterContext.HttpContext.Request["token"];
                var sessionKey = HttpContext.Current.Session["Token"];
                if (token != null || sessionKey != null || cToken != null)
                {//eWFuc2hpLGE=
                    token = token ?? sessionKey.ToString() ?? cToken.Value;
                    var data = new { key = token };
                    //如果token不為空則去服務驗證token是否有效
                    HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(data));
                    httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                    var httpClient = new HttpClient();
                    var responseJson = httpClient.PostAsync(SSOURL + "/ValidateToken", httpContent)
                        .Result.Content.ReadAsStringAsync().Result;
                    var myToken = JsonConvert.DeserializeObject<JH_OEMR_Model.MyToken>(responseJson);
                    if (myToken.ValidateToken)
                    {
                        isLogined = true;
                    }
                }

                if (!isLogined)
                    filterContext.HttpContext.Response.Redirect(SSOURL+"?backUrl=" + filterContext.HttpContext.Request.Url, true);
            }
            catch (Exception ex)
            {
                filterContext.HttpContext.Response.Write("aaaaa"+ex.Message.ToString());
                throw;
            }
        }

CS端集成SSO:

CS端載入BS頁面時,先判斷是否模擬登錄,如未登錄,模擬登錄,然後訪問BS端網址帶上token即可

主要代碼:

private static void LoginSSO()
        {
            var data = new { name = UName, passWord = UPwd, backUrl = string.Empty };
            HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(data));
            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var httpClient = new HttpClient();
            var responseJson = httpClient.PostAsync(SSOURL+"/Login", httpContent)
                .Result.Content.ReadAsStringAsync().Result;
            var myToken = JsonConvert.DeserializeObject<MyMsg>(responseJson);
            if (myToken.IsLogined)
            {
                IsLoginedSSO = true;
            }
        }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天我們來說下如何在windows下使用docker運行.net core,既然是docker,那麼我們首先得在windows上安裝docker。 在Windows安裝 docker 有兩種選擇 :1、docker for windows2、docker toolbox 區別:docker for ...
  • yyyyyyyyyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyyyyyyyyy ...
  • 使用 ASP.NET Core MVC 創建 Web API 使用 ASP.NET Core MVC 創建 Web API(一) 使用 ASP.NET Core MVC 創建 Web API(二) 十、添加 GetBookItem 方法 1) 在Visual Studio 2017中的“解決方案資源 ...
  • 索引: 目錄索引 一.API 列表 1.Set<M, F>(Expression<Func<M, F>> propertyFunc, F newVal) 如: .Set(it => it.BodyMeasureProperty, "{xxx:yyy,mmm:nnn,zzz:aaa}") 用於 單表 ...
  • 今天自己開發了一個訂機票的微信公眾號,功能基本已經完成,然後想部署到伺服器實際測試下。結果部署上去出現各種問題。先安裝asp.net core模塊,然後發現資料庫並不像在開發時一樣,執行ef的命令行語句就可以了。可以到輸出目錄找到對應的sql語句,到伺服器上執行一下。 後來部署上去以後,發現很多對應... ...
  • 轉自:https://blog.csdn.net/jie_liang/article/details/77340905 用以記錄: 在sql查詢中為了提高查詢效率,我們常常會採取一些措施對查詢語句進行sql優化,下麵總結的一些方法,有需要的可以參考參考。 1.對查詢進行優化,應儘量避免全表掃描,首先 ...
  • //通過ClassName獲取div,使用setAttribute設置div禁止點擊 pointer-events: none;是css3新出現的屬性,意思就是禁止滑鼠點擊事件,當元素中有這一屬性時,鏈接、點擊事件統統失效 ...
  • 通過註解(特性)的方式進行對象的註冊與註入,方便,靈活! 本篇主要講如何去實現,下一篇主要講如何把它集成到mvc和api環境里,實現自動的註入! spring ioc工作的過程大致為,統一的註冊組件,攔截當前請求,統一的註入當前請求所需要的組件,事實上,說到這事,.net也完全可以實現這個功能和工作 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...