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/
Asp.net 实现只能允许一个账号同时只能在一个地方登录的更多相关文章
- asp.net mvc 简单实现一个账号只能在一个地方登录
原理: 假设用户在机器A登陆后, 这时用户再次在机器B登陆,会以当前会话的SessionID作为键,用户id作为值,插入dictionary集合中,集合再保存在application(保存在服务器 ...
- shiro 实现单用户登录,一个用户同一时刻只能在一个地方登录
我这里 shiro 并没有集成 springMVC,直接使用 ini 配置文件. shiro.ini [main] # Objects and their properties are defined ...
- ASP.NET Core MVC 打造一个简单的图书馆管理系统 (修正版)(二)数据库初始化、基本登录页面以及授权逻辑的建立
前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/asp ...
- ASP.NET Core 3.0 一个 jwt 的轻量角色/用户、单个API控制的授权认证库
目录 说明 一.定义角色.API.用户 二.添加自定义事件 三.注入授权服务和中间件 三.如何设置API的授权 四.添加登录颁发 Token 五.部分说明 六.验证 说明 ASP.NET Core 3 ...
- 解决微信授权回调页面域名只能设置一个的问题 [php]
最终的解决方案是:https://github.com/liuyunzhuge/php_weixin_proxy,详细的介绍请往下阅读. 在做项目集成微信登录以及微信支付的时候,都需要进行用户授权.这 ...
- 如何快速从一个Storage Account拷贝到另一个账号
当您有两个Storage Account的时候,怎样快速做到从一个账号拷贝到另一个账号呢.当拷贝的文件比较,例如100多G(VHD文件). http://code.msdn.microsoft.com ...
- 怎么取消 Windows Server 2012 r2 RDP 限制每个用户只能进行一个会话(转)
在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...
- 怎么取消 Windows Server 2012 RDP 限制每个用户只能进行一个会话
在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...
- HttpActionDescriptor,ASP.NET Web API又一个重要的描述对象
HttpActionDescriptor,ASP.NET Web API又一个重要的描述对象 通过前面对“HttpController的激活”的介绍我们已经知道了ASP.NET Web API通过Ht ...
随机推荐
- 小程序网络请求arraybuffer 转为base64
wx.request({ url: result.tempFilePath, method: 'GET', responseType: 'arraybuffer', success: function ...
- Yii2之事件处理
通过事件(Event)处理,可以在某个特定时刻执行指定的代码,可以解耦代码,同时也增加了可维护性,通常,事件在客户端软件中比较好理解,比如onClick,onFocus,当点击按钮,获取到焦点时执行指 ...
- basic--factory
<?php /* 工厂模式: 由工厂类根据参数来决定创建出哪一种产品类的实例: 工厂类是指包含了一个专门用来创建其他对象的方法的类.所谓按需分配,传入参数进行选择,返回具体的类.工厂模式的最主要 ...
- Android FrameLayout单帧布局
FrameLayout:所有控件位于左上角,并且直接覆盖前面的子元素. 在最上方显示的层加上: android:clickable="true" 可以避免点击上层触发底层. 实例: ...
- 【leetcode刷题笔记】Sort List
Sort a linked list in O(n log n) time using constant space complexity. 题解:实现一个链表的归并排序即可.主要分为三部分: 1.找 ...
- P3768 【简单的数学题】
P3768 [简单的数学题] \(Ans=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ijgcd(i,j)\) \(=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ij\ ...
- python作用域和js作用域的比较
1.python和js一样,作用域链在执行方法之前就已经创建了 # 下面的执行结果就是aa,原因是这点python和js一样,作用域链已经创建了,不会去改变 xo="aa" def ...
- hd acm1048
Problem Description Julius Caesar lived in a time of danger and intrigue. The hardest situation Caes ...
- 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% ...
- UESTC 1061 秋实大哥与战争 线段树区间合并
秋实大哥与战争 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 男儿何不带吴钩, ...