C# 单点登录

1.什么情况下会用到单点登录

       刚开始框架中也是没有单点登录此模块的,有一次需要在Winform系统中嵌入Web页面,整合两个系统。Web页面的用户信息验证一直没找到什么好的 解决办法,刚开始的办法是通过往网页地址后面自动加上登录用户名和密码,发送到后台进行登录;这样也达到了整合的目的,但是总感觉比较别扭,直接把用户名 和密码暴露在地址栏肯定存在安全隐患。后来经过一番波折在网上找到类似的解决办法,利用单点登录的方案达到了比较好的效果;

       除了上面说的Winform系统中嵌入Web页面这种情况,还有经常在自己公司系统中整合一些合作伙伴的系统,如此打包销售更有市场竞争力,这样首要解 决的问题也是登录入口统一;如今行业软件现状,不像十年前了只有那么一两套系统,讲究着用就行了,现在没有用上十来个系统就不叫信息化了,所以你能提供一 个单点登录的解决方案也是一大卖点;再就是现在的软件公司不管大小靠一个产品就能生存的很难了,基本都是最大化的挖掘客户的需求,最好能提供一整套的解决 方案,这些系统能整体销售更好,而单个产品销售也得支持。所以不管是客户的需求还是内部的产品都会存在系统间整合的问题,而利用单点登录至少能解决用户统 一验证的问题;

2.具体代码

1.登录模块

 

        /// <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和有效性

         //<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类中的相关方法

 

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;
        }

       
    }

 以上是核心地方,所以贴出来。 如有问题,请下载源码  查看详细!~

转载于:https://www.cnblogs.com/it888/p/4013455.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单点登录(Single Sign-On,SSO)是指用户只需登录一次,即可在多个应用系统中访问被授权的资源,而无需再次登录或提供身份验证信息。在 C# 中,可以通过以下步骤实现单点登录: 1. 配置身份认证和授权。 在 Web.config 文件中,配置身份认证和授权,例如: ``` <system.web> <authentication mode="Forms"> <forms name=".ASPXAUTH" loginUrl="~/Account/Login" timeout="2880" /> </authentication> <authorization> <deny users="?" /> </authorization> </system.web> ``` 2. 实现登录页面。 在登录页面中,用户输入用户名和密码,然后将其传递到服务器进行验证。如果验证通过,则使用 FormsAuthentication.SetAuthCookie 方法创建认证票证,并跳转到主页。 ``` if (IsValid(username, password)) { FormsAuthentication.SetAuthCookie(username, false); return RedirectToAction("Index", "Home"); } else { ModelState.AddModelError("", "The user name or password is incorrect."); return View(); } ``` 3. 在其他应用系统中验证认证票证。 其他应用系统可以通过检查认证票证来验证用户的身份。可以使用 FormsAuthentication.Decrypt 方法解密认证票证,然后检查票证是否过期或是否被篡改。 ``` HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie != null) { FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); if (authTicket != null && !authTicket.Expired && authTicket.Name == username) { // User is authenticated } } ``` 以上是单点登录的基本实现步骤,但具体实现还需要根据实际需求进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值