• Asp.net 实现只能允许一个账号同时只能在一个地方登录


    先上帮助类:

    /// <summary>
        /// 单点登录帮助类
        /// </summary>
        public class SSOHelper
        {
            /// <summary>
            /// 登录后执行
            /// </summary>
            /// <param name="UserID">用户标识</param>
            public void LoginRegister(string UserID)
            {
                Hashtable hOnline = (Hashtable)System.Web.HttpContext.Current.Application["Online"];
                if (hOnline != null)
                {
                    IDictionaryEnumerator idE = hOnline.GetEnumerator();
                    string strKey = "";
                    while (idE.MoveNext())
                    {
                        if (idE.Value != null && idE.Value.ToString().Equals(UserID))
                        {
                            //already login 
                            strKey = idE.Key.ToString();
                            hOnline[strKey] = "XXXXXX";
                            break;
                        }
                    }
                }
                else
                {
                    hOnline = new Hashtable();
                }
    
                hOnline[System.Web.HttpContext.Current.Session.SessionID] = UserID;
                System.Web.HttpContext.Current.Application.Lock();
                System.Web.HttpContext.Current.Application["Online"] = hOnline;
                System.Web.HttpContext.Current.Application.UnLock();
            }
    
            /// <summary>
            /// 检查是否唯一登录
            /// </summary>
            /// <returns></returns>
            public static bool CheckOnline()
            {
                Hashtable hOnline = (Hashtable)System.Web.HttpContext.Current.Application["Online"];
                if (hOnline != null)
                {
                    IDictionaryEnumerator idE = hOnline.GetEnumerator();
                    while (idE.MoveNext())
                    {
                        if (idE.Key != null && idE.Key.ToString().Equals(System.Web.HttpContext.Current.Session.SessionID))
                        {
                            //already login
                            if (idE.Value != null && "XXXXXX".Equals(idE.Value.ToString()))
                            {
                                hOnline.Remove(System.Web.HttpContext.Current.Session.SessionID);
                                System.Web.HttpContext.Current.Application.Lock();
                                System.Web.HttpContext.Current.Application["Online"] = hOnline;
                                System.Web.HttpContext.Current.Application.UnLock();
                                return false;
                            }
                            break;
                        }
                    }
                }
                return true;
            }
    
            /// <summary>
            /// Global文件的SessionEnd事件中增加此代码
            /// </summary>
            public static void GlobalSessionEnd()
            {
                Hashtable hOnline = (Hashtable)System.Web.HttpContext.Current.Application["Online"];
                if (hOnline[System.Web.HttpContext.Current.Session.SessionID] != null)
                {
                    hOnline.Remove(System.Web.HttpContext.Current.Session.SessionID);
                    System.Web.HttpContext.Current.Application.Lock();
                    System.Web.HttpContext.Current.Application["Online"] = hOnline;
                    System.Web.HttpContext.Current.Application.UnLock();
                }
            }
    
        }

    在登录的时候调用一下LoginRegister方法

    Global.asax中:

    protected void Session_End(object sender, EventArgs e)
            {
                ltGameStore.Common.SSOHelper.GlobalSessionEnd();
            }

    剩下的就是在每次客户端对服务器有请求的时候验证当前会话ID是否被注销掉了(被其他用户挤掉)

    我用的是一个继承Controller的基类,重写里面的OnAuhorization方法:

    /// <summary>
            /// 在进行授权时调用
            /// </summary>
            /// <param name="filterContext"></param>
            protected override void OnAuthorization(AuthorizationContext filterContext)
            {
                //不能应用在子方法上
                if (filterContext.IsChildAction)
                    return;
    
                //如果没有登录,则跳转到登录视图
                if (WorkContext.Action != "login")
                {
                    if (!TicketHelper.IsLogin())
                    {
                        filterContext.Result = new RedirectResult("/Account/login");
                    }
                }
    
                if (!SSOHelper.CheckOnline())
                {
                    filterContext.Result = PromptView("您的账号已在别处登录");
                }
    
    
                //如果当前用户不是管理员
                //if (WorkContext.AdminGid == 1)
                //{
                //    if (WorkContext.IsHttpAjax)
                //        filterContext.Result = new ContentResult { Content = "404" };
                //    else
                //        filterContext.Result = new RedirectResult("/");
                //    return;
                //}
            }

    注意,这样写的话会有个问题,每次客户端请求的SessionID都不一样,这样就无法校验了,搜了一下解决方法,在重写的Initialize方法(继承Controller的基类中)中不断的注册SessionId:

    /// <summary>
            /// 初始化调用构造函数后可能不可用的数据
            /// </summary>
            /// <param name="requestContext"></param>
            protected override void Initialize(RequestContext requestContext)
            {
                base.Initialize(requestContext);
                Session["SessionId"] = Session.SessionID;
            }

    参考以下:

    http://www.cnblogs.com/xlhblogs/archive/2012/03/29/2422804.html

    http://czhjq.blog.163.com/blog/static/85014962010112263336615/

  • 相关阅读:
    failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected 排坑指南
    使用labelme制作自己的数据集
    linux安装anaconda3 conda: command not found
    windows端运行.sh脚本
    安装easydict
    tensorflow安装排坑笔记
    Dev怎么调试,怎么调试不了???
    NameError: name 'QApplication' is not defined 的解决办法
    绝对路径和相对路径
    关于Pycharm总是Indexing很久的问题
  • 原文地址:https://www.cnblogs.com/New-world/p/3865939.html
Copyright © 2020-2023  润新知