单点登陆 ---密钥

摘要:
U=xxx&令牌=FB92B341DBDB59D7,其中u是加密的用户名,token是系统B和系统A之间的单点登录握手密钥。控制器中的方法代码如下:[AllowAnonymon][NoTransaction]//////执行单点登录////publicActionResultSingleSignOn(){RedirectToRouteResult=null;stringsertokenString=Request.Params[“token”];stringuserName=Request.PParams[“u”]; stringlginname=DESHelper。解密;stringtoken=系统。配置设置。AppSettings[“token”];如果(!

一、需求描述

现在有A系统和B系统,需要在A系统进行单点登陆到B系统。

二、B系统要做事

1、提供一个可以让A系统登陆的网址

http://localhost:8083/Account/SingleSignOn/?u=xxx&token=FB92B341DBDB59D7

其中,u为加密后的用户名,token为B系统与A系统单点登录握手密钥

2、控制器中的方法代码如下

[AllowAnonymous]
        [NoTransaction]
        /// <summary>
        /// 执行单点登录
        /// </summary>
        public ActionResult SingleSignOn()
        {
            RedirectToRouteResult result = null;
            string usertokenString = Request.Params["token"];
            string userName = Request.Params["u"];
            string loginname = DESHelper.Decrypt(userName);
            string token = System.Configuration.ConfigurationSettings.AppSettings["token"];
            if (!string.IsNullOrEmpty(usertokenString))
            {
                if (usertokenString != token || string.IsNullOrEmpty(userName))
                {
                    result = RedirectToAction("NotRole", "Home");
                }
                else
                {
                    MembershipUser user = Membership.GetUser(loginname, false);
                    if (user == null)
                    {
                        //用户不存在
                        result = RedirectToAction("UserNotExist", "Home");
                    }
                    else if (user.IsLockedOut)
                    {
                        //用户被锁定
                        result = RedirectToAction("UserIsLockedOut", "Home");
                    }
                    else if (!user.IsApproved)
                    {
                        //用户未启用 
                        result = RedirectToAction("UserIsApproved", "Home");
                    }
                    else
                    {
                        LogInfoService lis = new LogInfoService();
                        LogInfo lilist = new LogInfo(ProfileHelper.GetName(), "登录", "登录");
                        lis.Save(lilist);
                        result = RedirectToAction("Index", "Member");
                    }
                }
            }
            else
                result = RedirectToAction("NotRole", "Home");

            Session["userid"] = loginname;
            System.Web.Security.FormsAuthentication.SetAuthCookie(loginname, true);
            return result;
        }

首先我们要接过传过来的token和用户名u,

其次我们要对用户名进行解密

最后我们要比较token是不是A系统认证的token,并查找用户名是否存在

如果都满足则让用户登陆

3、解密用户名,要步骤2中,要对传过来的用户名进行解密,加密解决的方法都提供了

/// <summary>
    /// DES对称加密
    /// </summary>
    public static class DESHelper
    {
        /// <summary>
        /// 根据用户名解密
        /// </summary>
        /// <param name="val"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        public static string Decrypt(string val, string userid = "")
        {

            var key = GetKey(userid);
            var iv = GetDefaultIV();
            return Decrypt(val, key, iv);
        }

        /// <summary>
        /// 根据用户名加密
        /// </summary>
        /// <param name="val"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        public static string Encrypt(string val, string userid = "")
        {

            var key = GetKey(userid);
            var iv = GetDefaultIV();
            return Encrypt(val, key, iv);
        }

        /// <summary>
        /// Des加密方法
        /// </summary>
        /// <param name="val"></param>
        /// <param name="key"></param>
        /// <param name="IV"></param>
        /// <returns></returns>
        public static string Encrypt(string val, string key, string IV, CipherMode cipherMode = CipherMode.ECB)
        {
            try
            {
                if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(key))
                {
                    throw new Exception("密钥和偏移向量不足8位");
                }

                if (key.Length > 8) key = key.Substring(0, 8);
                if (IV.Length > 8) IV = IV.Substring(0, 8);

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] btKey = Encoding.Default.GetBytes(key);
                byte[] btIV = Encoding.Default.GetBytes(IV);
                StringBuilder builder = new StringBuilder();
                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] inData = Encoding.Default.GetBytes(val);
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);
                        cs.FlushFinalBlock();
                    }

                    foreach (byte num in ms.ToArray())
                    {
                        builder.AppendFormat("{0:X2}", num);
                    }
                } 
                return builder.ToString();
            }
            catch // (Exception ex)
            {
                return "";
            }
        }

        /// <summary>
        /// Des解密方法
        /// cbc模式:(key值和iv值一致)
        /// </summary>
        /// <param name="val"></param>
        /// <param name="key"></param>
        /// <param name="IV"></param>
        /// <returns></returns>
        public static string Decrypt(string val, string key, string IV, CipherMode cipherMode = CipherMode.ECB)
        {
            try
            {
                if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(key))
                {
                    throw new Exception("密钥和偏移向量不足8位");
                }

                if (key.Length > 8) key = key.Substring(0, 8);
                if (IV.Length > 8) IV = IV.Substring(0, 8);

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] btKey = Encoding.Default.GetBytes(key);
                byte[] btIV = Encoding.Default.GetBytes(IV);
                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] inData = new byte[val.Length / 2];
                    for (int i = 0; i < (val.Length / 2); i++)
                    {
                        int num2 = Convert.ToInt32(val.Substring(i * 2, 2), 0x10);
                        inData[i] = (byte)num2;
                    }

                    using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);
                        cs.FlushFinalBlock();
                    }

                    return Encoding.Default.GetString(ms.ToArray());
                }
            }
            catch // (System.Exception ex)
            {
                return "";
            }
        }

        /// <summary>
        /// Md5加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string MD5(string str)
        {
            if (string.IsNullOrEmpty(str)) return str;
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            string encoded = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(str))).Replace("-", "");
            return encoded;
        }

        private static string GetKey(string key)
        {
            string defaultKey = "C560F02F693B4A0BA62D2B3B5FB74534";
            string sTemp = defaultKey;
            if (!string.IsNullOrEmpty(key))
            {
                sTemp = string.Concat(key, defaultKey.Substring(key.Length, 32 - key.Length));
            }
            return MD5(sTemp).Substring(0, 8);
        }
        /// <summary>   
        /// 获得初始向量IV 
        /// </summary>   
        /// <returns>初试向量IV</returns>   
        private static string GetDefaultIV()
        {
            string sTemp = "87DE696F56DE49C0B96EB85139A48805";
            return MD5(sTemp).Substring(0, 8);
        }
    }

三、A系统要做的事

1、直接访问B提供的网址

http://localhost:8083/Account/SingleSignOn/?token=FB92B341DBDB59D7&u="+userName

其中用户名userName是进行加密了的

2、加密用户名的方法

public string GetUserId()
        {
           return Encrypt(HttpContext.Current.User.Identity.Name);
        }

        public string Encrypt(string val)
        {
            var key = "87DE696F";//测试期间请用此key使用
            try
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] btKey = Encoding.Default.GetBytes(key);
                byte[] btIV = Encoding.Default.GetBytes(key);
                StringBuilder builder = new StringBuilder();
                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] inData = Encoding.Default.GetBytes(val);
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);
                        cs.FlushFinalBlock();
                    }

                    foreach (byte num in ms.ToArray())
                    {
                        builder.AppendFormat("{0:x2}", num);
                    }
                }
                return builder.ToString();
            }
            catch // (Exception ex)
            {
                return "";
            }
        }

免责声明:文章转载自《单点登陆 ---密钥》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇超级菜菜鸟全程架站攻略(Mysql+Apche+PHP+Phpmyadmin+Zend,含本机安装)让Java线程池实现任务阻塞执行的一种可行方案下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

.net Core 调用微信Jsapi接口,H5解析二维码

项目里需要用到扫描二维码,自己实现,不会。 找到了两种解决方案: 通过reqrcode.js,这是一个前端解析二维码内容的js库。如果二维码比较清晰,用这种效果也不错 调用微信扫一扫功能,这种效果很好。但是调试接口超级麻烦。 具体实现:前端代码(vue)(前端用到 vux) <template> <div class="main"&g...

计算同比和环比增长率

      今天做的项目中,遇到一个计算同期环比和上期环比的计算并显示出来。这是用ssm框架   代码示例:    @RequiresPermissions("analysis:analysis:smartSearch") @RequestMapping(value = "/analysis/analysis/smartSearch") p...

JavaSE基础之double数据类型的格式化

JavaSE基础之double数据类型的格式化 1、double 数据类型的格式化工具类:DoubleFormatUtil.java 1 package cn.com.zfc.util; 2 3 import java.math.BigDecimal; 4 import java.text.DecimalFormat; 5 import jav...

redis分布式共享锁模拟抢单的实现

本篇内容主要讲解的是redis分布式锁,并结合模拟抢单的场景来使用,内容节点如下: jedis的nx生成锁 如何删除锁 模拟抢单动作 1.jedis的nx生成锁 对于分布式锁的生成通常需要注意如下几个方面: 创建锁的策略:redis的普通key一般都允许覆盖,A用户set某个key后,B在set相同的key时同样能成功,如果是锁场景,那就无法知道到底...

Java—视频处理

  原始视频通常需要经过编码处理,生成m3u8和ts文件方可基于HLS协议播放视频。通常用户上传原始视频,系统 自动处理成标准格式,系统对用户上传的视频自动编码、转换,最终生成m3u8文件和ts文件, 处理流程如下:   1、用户上传视频成功   2、系统对上传成功的视频自动开始编码处理   3、用户查看视频处理结果,没有处理成功的视频用户可在管理界面再次...

微服务-使用Redis实现分布式缓存

在单体中对于key信息和用户信息是放在内存中放的,通过session进行管理。 微服务是要放在分布式缓存中,以实现服务的无状态化。 @Autowired privateStringRedisTemplate redisTemplate; @Value("${file.prefix}") privateString imgPrefix;...