刚开始框架中也是没有单点登陆此模块的,有一次须要在Winform系统中嵌入Web页面,整合两个系统。Web页面的用户信息验证一直没找到什么好的 解决办法,刚开始的办法是经过往网页地址后面自动加上登陆用户名和密码,发送到后台进行登陆;这样也达到了整合的目的,可是总感受比较别扭,直接把用户名 和密码暴露在地址栏确定存在安全隐患。后来通过一番波折在网上找到相似的解决办法,利用单点登陆的方案达到了比较好的效果;安全
除了上面说的Winform系统中嵌入Web页面这种状况,还有常常在本身公司系统中整合一些合做伙伴的系统,如此打包销售更有市场竞争力,这样首要解 决的问题也是登陆入口统一;现在行业软件现状,不像十年前了只有那么一两套系统,讲究着用就好了,如今没有用上十来个系统就不叫信息化了,因此你能提供一 个单点登陆的解决方案也是一大卖点;再就是如今的软件公司无论大小靠一个产品就能生存的很难了,基本都是最大化的挖掘客户的需求,最好能提供一整套的解决 方案,这些系统能总体销售更好,而单个产品销售也得支持。因此无论是客户的需求仍是内部的产品都会存在系统间整合的问题,而利用单点登陆至少能解决用户统 一验证的问题;框架
1.登陆模块ui
/// <summary> /// 登陆 /// </summary> /// <param name="userId"></param> /// <param name="tokenid"></param> /// <returns></returns> public bool SignIn(string userId, string userName, out Guid tokenid) { TokenInfo existToken = TokenManager.GetToken(userId); //查询uid是否存在 if (existToken != null) { tokenid = existToken.tokenId; return true; } TokenInfo token = new TokenInfo() { tokenId = Guid.NewGuid(), IsValid = true, CreateTime = DateTime.Now, ActivityTime = DateTime.Now, UserId = userId, UserName = userName }; tokenid = token.tokenId; return TokenManager.AddToken(token);//添加到Tokenlist集合中 }
2.验证是否存在Token和有效性spa
//<summary> //是否有效登陆 //</summary> //<param name="token"></param> //<returns></returns> public AuthResult ValidateToken(string token) { Guid guid = GetGuid(token, Guid.NewGuid()); //验证Token合法性 AuthResult result = new AuthResult() { ErrorMsg = "Token不存在" }; TokenInfo existToken = TokenManager.GetToken(guid); //检查Token是否存在TokenList中 if (existToken != null) { #region 客户端IP不一致 //if (existToken.RemoteIp != entity.RemoteIp) //{ // result.ErrorMsg = "客户端IP不一致"; //} #endregion if (existToken.IsValid == false) { double totalSeconds = ((TimeSpan)(DateTime.Now - existToken.ActivityTime)).TotalSeconds; //Token从生成到目前,经历了多少时间 result.ErrorMsg = "Token经历了:" + totalSeconds + "\r\nToken已过时:" + existToken.ActivityTime + "\r\n" + "如今时间:" + DateTime.Now.ToLocalTime(); TokenManager.RemoveToken(existToken.tokenId);//移除 } else { result.User = new UserInfo() { UserId = existToken.UserId, UserName = existToken.UserName, CreateDate = existToken.CreateTime }; result.ErrorMsg = string.Empty; } } return result; }
3.Token类中的相关方法orm
public class TokenManager { private const int _TimerPeriod = 60000;//60秒,这里设置Token过时时间为60秒 private static Timer thTimer; static List<TokenInfo> tokenList = null; static TokenManager() { tokenList = new List<TokenInfo>(); thTimer = new Timer(_ThreadTimerCallback, null, _TimerPeriod, _TimerPeriod); } private static void _ThreadTimerCallback(Object state) { DateTime now = DateTime.Now; Monitor.Enter(tokenList); try { // Searching for expired users foreach (TokenInfo t in tokenList) { if (((TimeSpan)(now - t.ActivityTime)).TotalMilliseconds > _TimerPeriod) { t.IsValid = false;//失效 } } } finally { Monitor.Exit(tokenList); } } public static bool AddToken(TokenInfo entity) { tokenList.Add(entity); return true; } public static bool RemoveToken(Guid token) { TokenInfo existToken = tokenList.SingleOrDefault(t => t.tokenId == token); if (existToken != null) { tokenList.Remove(existToken); return true; } return false; } public static TokenInfo GetToken(Guid token) { TokenInfo existToken = tokenList.SingleOrDefault(t => t.tokenId == token); return existToken; } public static TokenInfo GetToken(string userId) { TokenInfo existToken = tokenList.SingleOrDefault(t => (t.UserId == userId && t.IsValid == true)); return existToken; } }
以上是核心地方,因此贴出来。 若有问题,请下载源码 查看详细!~blog