單點登錄 ---密鑰

1、需求描述html

如今有A系統和B系統,須要在A系統進行單點登錄到B系統。ide

2、B系統要作事post

一、提供一個可讓A系統登錄的網址測試

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

其中,u爲加密後的用戶名,token爲B系統與A系統單點登陸握手密鑰加密

二、控制器中的方法代碼以下spa

[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,code

其次咱們要對用戶名進行解密orm

最後咱們要比較token是否是A系統認證的token,並查找用戶名是否存在htm

若是都知足則讓用戶登錄

三、解密用戶名,要步驟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);
        }
    }

 

 

 

 

3、A系統要作的事

一、直接訪問B提供的網址

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

其中用戶名userName是進行加密了的

二、加密用戶名的方法

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 "";
            }
        }
相關文章
相關標籤/搜索