欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于ASP.NET實現(xiàn)單點登錄(SSO)的示例代碼

 更新時間:2022年05月10日 10:24:49   作者:CoolDog;  
SSO英文全稱Single?Sign?On(單點登錄)。SSO是在多個應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)。本文為大家分享了基于ASP.NET實現(xiàn)單點登錄(SSO)的示例代碼,需要的可以參考一下

背景

先上個圖,看一下效果:

SSO英文全稱Single Sign On(單點登錄)。SSO是在多個應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)。它包括可以將這次主要的登錄映射到其他應(yīng)用中用于同一個用戶的登錄的機制。

它是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一。(本段內(nèi)容來自百度百科)   話不多說,開擼!

邏輯分析

Client1:用戶A在電腦1上登錄管理員賬號

Service:驗證用戶A登陸成功生成Admin賬號的Token令牌,分別存儲電腦1的cookie中服務(wù)器的全局變量中(可以是session,緩存,全局變量,數(shù)據(jù)庫)

Client2:用戶B在電腦2上登錄管理員賬號

Service:驗證用戶B登陸成功重新生成Admin賬號的Token令牌,分別存儲電腦2的cookie中服務(wù)器的全局變量中(可以是session,緩存,全局變量,數(shù)據(jù)庫)

Client1:觸發(fā)驗證:

1,判斷服務(wù)器全局變量是否過期,提示:身份信息過期,請重新登錄。

2,判斷客戶端的cookie是否過期,提示:長時間未登錄,已下線。

3,判斷電腦1上的cookie與服務(wù)器全局變量相比是否一致。提示:此用戶已在別處登陸!你被強制下線!

代碼實現(xiàn)

Service

1,創(chuàng)建一個服務(wù)器校驗登錄類,代碼如下

using Coldairarrow.Business;
using Coldairarrow.Util;
using System;
using System.Text;
using System.Web.Mvc;

namespace Coldairarrow.Web
{
    /// <summary>
    /// 校驗登錄
    /// </summary>
    public class CheckLoginAttribute : FilterAttribute, IActionFilter
    {
        public IOperator _operator { get; set; }
        public ILogger _logger { get; set; }

        /// <summary>
        /// Action執(zhí)行之前執(zhí)行
        /// </summary>
        /// <param name="filterContext">過濾器上下文</param>
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.RequestContext.HttpContext.Request;
            try
            {
                //若為本地測試,則不需要登錄
                if (GlobalSwitch.RunModel == RunModel.LocalTest)
                {
                    return;
                }

                //判斷是否需要登錄
                bool needLogin = !filterContext.ContainsAttribute<IgnoreLoginAttribute>();

                //獲取session里面的用戶id
                var uid = SessionHelper.Session["UserId"]?.ToString();

                if (needLogin)
                {
                    if (string.IsNullOrEmpty(uid))
                    {

                        //轉(zhuǎn)到登錄
                        RedirectToLogin();

                    }
                    else
                    {
                        var Cguid = filterContext.HttpContext.Request.Cookies["CToken"].Value?.ToString();
                        var Sguid = CacheHelper.Cache.GetCache(uid + "_SToken")?.ToString();



                        //判斷是否過期
                        if (string.IsNullOrEmpty(Cguid) || string.IsNullOrEmpty(Sguid))
                        {
                            //  過期  轉(zhuǎn)到登錄
                            ReturnLogin("身份信息以失效,請重新登陸!");
                            SessionHelper.Session["UserId"] = "";
                        }
                        else
                        {
                            //判斷用戶是否重復(fù)登陸
                            if (Sguid != Cguid)
                            {
                                //  過期  轉(zhuǎn)到登錄
                                ReturnLogin("此用戶已在別處登陸!你被強制下線!");
                                SessionHelper.Session["UserId"] = "";
                                //message = "已登陸";
                            }
                        }

                    }


                }







                //if (needLogin && !_operator.Logged())
                //{                //轉(zhuǎn)到登錄
                //    RedirectToLogin();
                //}
                //else
                //{


                //    string Id = _operator.UserId;
                //    _operator.Login(Id);
                //    return;
                //}
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                RedirectToLogin();
            }

            void RedirectToLogin()
            {
                if (request.IsAjaxRequest())
                {
                    filterContext.Result = new ContentResult
                    {
                        Content = new AjaxResult { Success = false, ErrorCode = 1, Msg = "未登錄" }.ToJson(),
                        ContentEncoding = Encoding.UTF8,
                        ContentType = "application/json"
                    };
                }
                else
                {
                    UrlHelper urlHelper = new UrlHelper(filterContext.RequestContext);
                    string loginUrl = urlHelper.Content("~/Home/Login");
                    string script = $@"    
            <html>
                <script>
                    top.location.href = '{loginUrl}';
                </script>
            </html>
            ";
                    filterContext.Result = new ContentResult { Content = script, ContentType = "text/html", ContentEncoding = Encoding.UTF8 };
                }
            }

            void ReturnLogin(string msg)
            {
                UrlHelper urlHelper = new UrlHelper(filterContext.RequestContext);
                string loginUrl = urlHelper.Content("~/Home/Login");
                string script = $@"    
            <html>
                <script>
                    alert('{msg}');
                    top.location.href = '{loginUrl}';
                </script>
            </html>
            ";
                filterContext.Result = new ContentResult { Content = script, ContentType = "text/html", ContentEncoding = Encoding.UTF8 };
            }
        }

        /// <summary>
        /// Action執(zhí)行完畢之后執(zhí)行
        /// </summary>
        /// <param name="filterContext"></param>
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {

        }
    }
}

2,創(chuàng)建一個mvc基控制器繼承Controller并且引用特性【CheckLogin】

3,業(yè)務(wù)控制器繼承BaseMvcController,并編寫登錄代碼。登陸成功后調(diào)用login方法,代碼如下:

/// <summary>
        /// 登錄
        /// </summary>
        /// <param name="userId">用戶邏輯主鍵Id</param>
        public void Login(string userId)
        {
            //保存登陸成功的令牌
            string Guid_str = "";
            //分配一個唯一標識符
            Guid_str = GuidHelper.GuidTo16String();
            HttpContext.Current.Response.Cookies["CToken"].Value = Guid_str;
            //給系統(tǒng)變量存儲一個值,Uid代表哪個用戶,GUID則是唯一標識符
            CacheHelper.Cache.SetCache(userId + "_SToken", Guid_str, new TimeSpan(0, 0, 30, 0, 0), ExpireType.Absolute);
            SessionHelper.Session["UserId"] = userId;
        }

4,這個時候基本就結(jié)束了,還需要增加一個忽略驗證的類,這個特性加在登錄頁面。意思是登錄頁面不需要觸發(fā)驗證;

5,服務(wù)器驗證的核心代碼有點不優(yōu)雅,不過實現(xiàn)邏輯了。有問題可以評論區(qū)溝通一下。本人用的是將token分別存儲在服務(wù)器緩存+客戶端cookie完成  ,大家服務(wù)器上可以用session,緩存,全局變量,數(shù)據(jù)庫等任意方式實現(xiàn);

總結(jié)

當用戶沒有重復(fù)登陸時,系統(tǒng)分配一個guid給用戶,并記錄用戶id和對應(yīng)的guid,這個用戶在線時系統(tǒng)變量存儲的用戶id以及對應(yīng)的guid值是不會變的,這時候有另外一個人用相同的賬號登陸時,會改變系統(tǒng)變量中用戶id對應(yīng)的guid。

這時候服務(wù)器就判斷出系統(tǒng)變量存儲的guid與用戶cookie存儲的guid不同時,就會強制用戶下線。

這個可以升級為指定N臺設(shè)備登錄,并且可以增加socket的方式通知其他電腦下線。由于業(yè)務(wù)不需要,就沒有增加即時通訊。

到此這篇關(guān)于基于ASP.NET實現(xiàn)單點登錄(SSO)的示例代碼的文章就介紹到這了,更多相關(guān)ASP.NET單點登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論