先上帮助类:

/// <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/

Asp.net 实现只能允许一个账号同时只能在一个地方登录的更多相关文章

  1. asp.net mvc 简单实现一个账号只能在一个地方登录

    原理:  假设用户在机器A登陆后,  这时用户再次在机器B登陆,会以当前会话的SessionID作为键,用户id作为值,插入dictionary集合中,集合再保存在application(保存在服务器 ...

  2. shiro 实现单用户登录,一个用户同一时刻只能在一个地方登录

    我这里 shiro 并没有集成 springMVC,直接使用 ini 配置文件. shiro.ini [main] # Objects and their properties are defined ...

  3. ASP.NET Core MVC 打造一个简单的图书馆管理系统 (修正版)(二)数据库初始化、基本登录页面以及授权逻辑的建立

    前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/asp ...

  4. ASP.NET Core 3.0 一个 jwt 的轻量角色/用户、单个API控制的授权认证库

    目录 说明 一.定义角色.API.用户 二.添加自定义事件 三.注入授权服务和中间件 三.如何设置API的授权 四.添加登录颁发 Token 五.部分说明 六.验证 说明 ASP.NET Core 3 ...

  5. 解决微信授权回调页面域名只能设置一个的问题 [php]

    最终的解决方案是:https://github.com/liuyunzhuge/php_weixin_proxy,详细的介绍请往下阅读. 在做项目集成微信登录以及微信支付的时候,都需要进行用户授权.这 ...

  6. 如何快速从一个Storage Account拷贝到另一个账号

    当您有两个Storage Account的时候,怎样快速做到从一个账号拷贝到另一个账号呢.当拷贝的文件比较,例如100多G(VHD文件). http://code.msdn.microsoft.com ...

  7. 怎么取消 Windows Server 2012 r2 RDP 限制每个用户只能进行一个会话(转)

    在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...

  8. 怎么取消 Windows Server 2012 RDP 限制每个用户只能进行一个会话

    在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...

  9. HttpActionDescriptor,ASP.NET Web API又一个重要的描述对象

    HttpActionDescriptor,ASP.NET Web API又一个重要的描述对象 通过前面对“HttpController的激活”的介绍我们已经知道了ASP.NET Web API通过Ht ...

随机推荐

  1. 小程序网络请求arraybuffer 转为base64

    wx.request({ url: result.tempFilePath, method: 'GET', responseType: 'arraybuffer', success: function ...

  2. Yii2之事件处理

    通过事件(Event)处理,可以在某个特定时刻执行指定的代码,可以解耦代码,同时也增加了可维护性,通常,事件在客户端软件中比较好理解,比如onClick,onFocus,当点击按钮,获取到焦点时执行指 ...

  3. basic--factory

    <?php /* 工厂模式: 由工厂类根据参数来决定创建出哪一种产品类的实例: 工厂类是指包含了一个专门用来创建其他对象的方法的类.所谓按需分配,传入参数进行选择,返回具体的类.工厂模式的最主要 ...

  4. Android FrameLayout单帧布局

    FrameLayout:所有控件位于左上角,并且直接覆盖前面的子元素. 在最上方显示的层加上: android:clickable="true" 可以避免点击上层触发底层. 实例: ...

  5. 【leetcode刷题笔记】Sort List

    Sort a linked list in O(n log n) time using constant space complexity. 题解:实现一个链表的归并排序即可.主要分为三部分: 1.找 ...

  6. P3768 【简单的数学题】

    P3768 [简单的数学题] \(Ans=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ijgcd(i,j)\) \(=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ij\ ...

  7. python作用域和js作用域的比较

    1.python和js一样,作用域链在执行方法之前就已经创建了 # 下面的执行结果就是aa,原因是这点python和js一样,作用域链已经创建了,不会去改变 xo="aa" def ...

  8. hd acm1048

    Problem Description Julius Caesar lived in a time of danger and intrigue. The hardest situation Caes ...

  9. Android系统篇之—-编写系统服务并且将其编译到系统源码中【转】

    本文转载自:http://www.wjdiankong.cn/android%E7%B3%BB%E7%BB%9F%E7%AF%87%E4%B9%8B-%E7%BC%96%E5%86%99%E7%B3% ...

  10. UESTC 1061 秋实大哥与战争 线段树区间合并

    秋实大哥与战争 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) 男儿何不带吴钩, ...