SSO的踢人模式/禁入模式
踢人模式
思路:
demo 数据
public class SampleData { public static List<UserlLogin> users; public static List<Role> roles; public static List<RoleWithControllerAction> rolewithControllaction; static SampleData() { // 初始化用户 users = new List<UserlLogin>() { new UserlLogin(){ Id=1, UserName="wangjie",UserPass="wangjie", RoleId=1,RememberMe=false}, new UserlLogin(){ Id=2, UserName ="senior1",UserPass="senior1", RoleId=2,RememberMe=false}, new UserlLogin(){ Id=3, UserName ="senior2",UserPass="senior2", RoleId=2,RememberMe=false}, new UserlLogin(){ Id=5, UserName="junior1",UserPass="junior1", RoleId=3,RememberMe=false}, new UserlLogin(){ Id=6, UserName="junior2",UserPass="junior2", RoleId=3,RememberMe=false}, new UserlLogin(){ Id=6, UserName="junior3",UserPass="junior3", RoleId=3,RememberMe=false} }; // 初始化角色 roles = new List<Role>() { new Role() { Id=1, RoleName="管理员", Description="管理员角色"}, new Role() { Id=2, RoleName="高级会员", Description="高级会员角色"}, new Role() { Id=3, RoleName="初级会员", Description="初级会员角色"} }; // 初始化角色控制器和Action对应类 rolewithControllaction = new List<RoleWithControllerAction>() { new RoleWithControllerAction(){ Id=1, ControllerName="AuthFilters", ActionName="AdminUser", RoleIds="1"}, new RoleWithControllerAction(){ Id=2, ControllerName="AuthFilters", ActionName="SeniorUser", RoleIds="1,2"}, new RoleWithControllerAction(){ Id=3, ControllerName="AuthFilters", ActionName="JuniorUser", RoleIds="1,2,3"}, new RoleWithControllerAction(){ Id=4, ControllerName="ActionFilters", ActionName="Index", RoleIds="2,3"} }; } }
public class Role { public int Id { get; set; } public string RoleName { get; set; } public string Description { get; set; } }
public class RoleWithControllerAction { public int Id { get; set; } public string ControllerName { get; set; } public string ActionName { get; set; } public string RoleIds { get; set; } }
public class UserlLogin { public int Id { get; set; } public string UserName { get; set; } public string UserPass { get; set; } public int RoleId { get; set; } public bool RememberMe { get; set; } }
实现登录模块
[HttpGet] public ActionResult Login() { if (Request["SSO"] != null && Request["SSO"].ToString() == "1") { ViewBag.Message = "对不起,别处有您帐号登录,您此处被迫下线!"; } var user = new UserlLogin(); return View(user); } [HttpPost] public ActionResult Login(UserlLogin users) { string userName = users.UserName; string userpass = users.UserPass; var dataUser = SampleData.users.Find(u => u.UserName == userName); if (dataUser != null) { if (dataUser.UserPass.Equals(userpass)) { Session["User"] = dataUser; if (users.RememberMe) FormsAuthentication.SetAuthCookie(users.UserName, true); //2880分钟有效期的cookie else FormsAuthentication.SetAuthCookie(users.UserName, false); //会话cookie return RedirectToAction("Register", "RegisterUser"); //return RedirectToAction("Welcome", "Home"); } else { TempData["Message"] = "密码错误!"; return RedirectToAction("Login"); } } else { ViewBag.Message = "用户不存在!"; return RedirectToAction("Login"); } } public ActionResult LogOut() { Session.Abandon(); FormsAuthentication.SignOut(); return RedirectToAction("Login"); }
实现用户注册模块
public ActionResult Register() { var user = Session["User"] as UserlLogin;//获取Session中登录的用户对象 var username = user.UserName; HttpContext httpContext = System.Web.HttpContext.Current; Hashtable userOnline = (Hashtable)httpContext.Application["Online"];//获取Application中的登录记录表 if (userOnline != null) { //遍历Application中的登录记录表 如果用户名相同,说明登录过,则做标记 IDictionaryEnumerator ide = userOnline.GetEnumerator(); while (ide.MoveNext()) { if (ide.Value != null && ide.Value.ToString() == username) { userOnline[ide.Key] = "-1"; //标记为”-1“,就代表当前用户”身份过期“ break; } } } else { userOnline = new Hashtable(); } //记录此次登录用户,因为如果重复登录,会删除掉之前的,现在保留 userOnline[Session.SessionID] = username; //Application 写入一个要加锁,因为是全局变量共享的 httpContext.Application.Lock(); httpContext.Application["Online"] = userOnline; httpContext.Application.UnLock(); return RedirectToAction("Welcome", "Home"); }
实现验证模块:
public class SSOAuthorize : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { Hashtable userOnline = (Hashtable)httpContext.Application["Online"]; if (userOnline != null) { var ide = userOnline.GetEnumerator(); if (userOnline.Count > 0) { while (ide.MoveNext()) { //判断登录时保存的Session是否与现在的Session相同 if (userOnline.Contains(httpContext.Session.SessionID)) { if (ide.Key != null && ide.Key.ToString() == httpContext.Session.SessionID) { if (ide.Value != null && ide.Value == "-1") { //说明该帐户已经被人重复登录 //把当前的这个Session所对应的用户”踢出“ userOnline.Remove(httpContext.Session.SessionID); httpContext.Application.Lock(); httpContext.Application["Online"] = userOnline; httpContext.Application.UnLock(); httpContext.Response.Redirect("/Account/Login?SSO=1", true); return false; } } } else { return false; } } } else return false; } return true; //return base.AuthorizeCore(httpContext); } }
加上对应的过滤器(其实可以写在一起,做个笔记就这样吧)
[Authorize] [SSOAuthorize] public ActionResult Welcome() { return View(); }
[UserAuthorize] [SSOAuthorize] public ActionResult AdminUser() { return View(); } [UserAuthorize] [SSOAuthorize] public ActionResult SeniorUser() { return View(); } [UserAuthorize] [SSOAuthorize] public ActionResult JuniorUser() { return View(); }
在Global.asax中加入以事件
protected void Session_End(object sender, EventArgs e) { Hashtable useronLine = (Hashtable)Application["Online"]; if (useronLine != null) { if (useronLine[Session.SessionID] != null) { useronLine.Remove(Session.SessionID); Application.Lock(); Application["Online"] = useronLine; Application.UnLock(); } } }
禁入模式
构Global.asax加入Session_Start事件
protected void Session_Start(object sender, EventArgs e) { Hashtable useronLine = (Hashtable)Application["Online"]; if (useronLine == null) { useronLine = new Hashtable(); } useronLine[Session.SessionID] = "Anonymous"; Application.Lock(); Application["Online"] = useronLine; Application.UnLock(); }
禁入模式控制器
protected override bool AuthorizeCore(HttpContextBase httpContext) { Hashtable userOnline = (Hashtable)httpContext.Application["Online"]; var user = httpContext.Session["User"] as UserlLogin; var username = user.UserName; if (userOnline != null) { if (userOnline.Count > 0) { var ide = userOnline.GetEnumerator(); while (ide.MoveNext()) { //说明不是同一个用户 if (ide.Key != null && ide.Key.ToString() != httpContext.Session.SessionID) { if (ide.Value != null && ide.Value.Equals(username)) { httpContext.Response.Redirect("/Account/Login?SSO=1", true); return false; } } } } else return false; } return true; //return base.AuthorizeCore(httpContext); }
登录之后的注册模块
[SSOForbid] public ActionResult Register() { var user = Session["User"] as UserlLogin;//获取Session中登录的用户对象 var username = user.UserName; HttpContext httpContext = System.Web.HttpContext.Current; Hashtable userOnline = (Hashtable)httpContext.Application["Online"];//获取Application中的登录记录表 //记录此次登录用户,因为如果重复登录,会删除掉之前的,现在保留 userOnline[Session.SessionID] = username; //Application 写入一个要加锁,因为是全局变量共享的 httpContext.Application.Lock(); httpContext.Application["Online"] = userOnline; httpContext.Application.UnLock(); return RedirectToAction("Welcome", "Home"); }