123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Net;
- using System.Security.Cryptography;
- using System.Text;
- using System.Web;
- using TEAMModelOS.SDK.Extension;
- namespace TEAMModelOS.Controllers.Third.Xkw
- {
- public abstract class OpenAuthClient
- {
- public string ClientName { get; protected set; }
- public string AppKey { get; protected set; }
- public string AppSecret { get; protected set; }
- public string RedirectUrl { get; set; }
- public string AccessToken { get; set; }
- public bool IsAuthorized
- {
- get { return isAccessTokenSet && !string.IsNullOrEmpty(AccessToken); }
- }
- protected bool isAccessTokenSet = false;
- public abstract string GetAuthorizationUrl();
- public abstract void GetAccessTokenByCode(string code, string schoolId);
- public OpenAuthClient(string clientId, string appSecret, string redirectUrl, string accessToken = null)
- {
- this.AppKey = clientId;
- this.AppSecret = appSecret;
- this.RedirectUrl = redirectUrl;
- this.AccessToken = accessToken;
- if (!string.IsNullOrEmpty(accessToken))
- {
- isAccessTokenSet = true;
- }
- }
- }
- public class XkwOAuthClient : OpenAuthClient
- {
- public string Domain { get; set; }
- public string AUTH_HOST { get; set; }
- public string AUTH_URL { get; set; }
- public string TOKEN_URL { get; set; }
- public string PROFILE_URL { get; set; }
- public string SERVICE_URL { get; set; }
- public string OpenId { get; set; }
- public string UserId { get; set; }
- public string Param { get; set; }
- /// <summary>
- /// 静默注册参数
- /// </summary>
- public string Extra { get; set; }
- public string ErrorMessage { get; set; }
- public XkwOAuthClient(string appKey, string appSecret, string redirectUrl, string oauthHost, string domain, string accessToken = null, string openid = null, string userId = null, string param = null)
- : base(appKey, appSecret, redirectUrl, accessToken)
- {
- ClientName = "Xkw Demo Client";
- OpenId = openid;
- UserId = userId;
- AUTH_HOST = oauthHost;
- AUTH_URL = AUTH_HOST + "authorize";
- TOKEN_URL = AUTH_HOST + "accessToken";
- PROFILE_URL = AUTH_HOST + "profile";
- Domain = domain;
- if (!(string.IsNullOrEmpty(accessToken) && string.IsNullOrEmpty(openid)))
- {
- isAccessTokenSet = true;
- }
- Param = param;
- }
- /// <summary>
- /// 进行认证
- /// </summary>
- /// <returns></returns>
- public override string GetAuthorizationUrl()
- {
-
- string redirect_uri= $"http://kong.sso.com:5000/authorized/xkw?{HttpUtility.UrlEncode(Param) }";
- string openSecret = "";
- if (!string.IsNullOrEmpty(OpenId))
- {
- openSecret = CryptoUtils.EncryptAES(OpenId, AppSecret);
- }
- string timespan = CryptoUtils.EncryptAES(GetTimeStamp(), AppSecret);
- string url = string.Format(AUTH_URL + "?client_id={0}&open_id={1}&service={2}&redirect_uri={3}×pan={4}",
- AppKey, openSecret, SERVICE_URL, redirect_uri, timespan);
- if (!string.IsNullOrEmpty(Extra))
- {
- url = string.Format("{0}&extra={1}", url, Extra);
- }
- //string retUrl = url + "&signature=" + SignatureHelper.GenerateSignature(url, AppSecret);
- string URLEncoder = string.Format(AUTH_URL + "?client_id={0}&open_id={1}&service={2}&redirect_uri={3}×pan={4}&extra={5}&signature={6}",
- HttpUtility.UrlEncode(AppKey), HttpUtility.UrlEncode(openSecret), HttpUtility.UrlEncode(SERVICE_URL), HttpUtility.UrlEncode(redirect_uri),
- HttpUtility.UrlEncode(timespan), HttpUtility.UrlEncode(Extra), HttpUtility.UrlEncode(SignatureHelper.GenerateSignature(url, AppSecret)));
- return URLEncoder.Replace("+", "%2B");
- }
- /// <summary>
- /// 根据code获取accessToken和用户信息
- /// </summary>
- /// <param name="code">code</param>
- /// <param name="schoolId">学校ID</param>
- public override void GetAccessTokenByCode(string code, string schoolId = null)
- {
- var client = new WebClient();
- client.Encoding = System.Text.Encoding.UTF8;
- try
- {
- //验证服务器证书回调自动验证
- ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
- string url = string.Format(TOKEN_URL + "?client_id={0}&code={1}&redirect_uri={2}", AppKey, code, RedirectUrl);
- string retUrl = url + "&signature=" + SignatureHelper.GenerateSignature(url, AppSecret);
- string data = client.DownloadString(retUrl);
- IDictionary<string, object> access_token_dic = data.ToObject<IDictionary<string, object>>();
- if (access_token_dic.ContainsKey("access_token"))
- AccessToken = $"{access_token_dic["access_token"]}";
- //获取用户openid
- string userProfileUrl = string.Format(PROFILE_URL + "?access_token={0}&schoolId={1}", AccessToken, schoolId);
- string ret = client.DownloadString(userProfileUrl);
- IDictionary<string, string> openId_dic = ret.ToObject<IDictionary<string, string>>();
- if (openId_dic.ContainsKey("open_id"))
- {
- OpenId = openId_dic["open_id"];
- }
- if (!string.IsNullOrEmpty(OpenId))
- {
- isAccessTokenSet = true;
- }
- else
- {
- if (openId_dic.ContainsKey("error"))
- {
- ErrorMessage = openId_dic["error"];
- }
- }
- }
- catch (Exception ex)
- {
- ErrorMessage = "服务器异常:" + ex.Message;
- }
- }
- /// <summary>
- /// 获取当前时间的时间戳
- /// </summary>
- /// <returns></returns>
- private string GetTimeStamp()
- {
- TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1, 0, 0, 0).Ticks);
- return ((long)ts.TotalMilliseconds).ToString();
- }
- }
- class SignatureHelper
- {
- /// <summary>
- /// 获取参数签名
- /// </summary>
- /// <param name="url">需要生成签名的url</param>
- /// <returns></returns>
- public static string GenerateSignature(String url, String secret)
- {
- int index = url.IndexOf("?");
- if (index > -1)
- {
- //将参数按参数名进行排序,然后对参数值进行加密
- string paramStr = url.Substring(index + 1);
- string[] paramKeyValues = paramStr.Split('&');
- Array.Sort(paramKeyValues);
- StringBuilder paramValueStr = new StringBuilder();
- foreach (string param in paramKeyValues)
- {
- string[] paramKeyValue = param.Split(new char[] { '=' }, 2);
- paramValueStr.Append(paramKeyValue[1]);
- }
- paramValueStr.Append(secret);
- return CryptoUtils.EncryptMD5(paramValueStr.ToString());
- }
- return "";
- }
- /// <summary>
- /// 获取参数签名
- /// </summary>
- /// <param name="paramDic">参数键值对</param>
- /// <param name="secret">加密秘钥</param>
- /// <returns></returns>
- public static string GenerateSignature(SortedDictionary<string, string> paramDic, String secret)
- {
- if (paramDic.Count > 0)
- {
- string paramStr = string.Concat(string.Join("", paramDic.Values), secret);
- return CryptoUtils.EncryptMD5(paramStr);
- }
- return "";
- }
- /// <summary>
- /// 获取参数签名
- /// </summary>
- /// <param name="paramList">参数键值对</param>
- /// <param name="secret">加密秘钥</param>
- /// <returns></returns>
- public static string GenerateSignature(SortedList<string, string> paramList, String secret)
- {
- if (paramList.Count > 0)
- {
- string paramStr = string.Concat(string.Join("", paramList.Values), secret);
- return CryptoUtils.EncryptMD5(paramStr);
- }
- return "";
- }
- }
- public class CryptoUtils
- {
- /// <summary>
- /// MD5加密
- /// </summary>
- /// <param name="encryptString">待加密的字符串</param>
- /// <returns>加密过的字符串</returns>
- public static string EncryptMD5(string encryptString)
- {
- byte[] result = Encoding.UTF8.GetBytes(encryptString);
- MD5 md5 = new MD5CryptoServiceProvider();
- byte[] output = md5.ComputeHash(result);
- string encryptResult = BitConverter.ToString(output).Replace("-", "");
- return encryptResult;
- }
- #region AES
- /// <summary>
- /// AES加密
- /// </summary>
- /// <param name="str">待加密字符串</param>
- /// <returns>加密后字符串</returns>
- public static string EncryptAES(string str, string key)
- {
- try
- {
- //分组加密算法
- AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
- byte[] inputByteArray = Encoding.UTF8.GetBytes(str);//得到需要加密的字节数组
- //设置密钥及密钥向量
- aes.Key = Encoding.UTF8.GetBytes(key);
- //aes.IV = Encoding.UTF8.GetBytes(key);
- aes.Mode = CipherMode.ECB;
- aes.Padding = PaddingMode.PKCS7;
- byte[] cipherBytes = null;
- using (MemoryStream ms = new MemoryStream())
- {
- using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
- {
- cs.Write(inputByteArray, 0, inputByteArray.Length);
- cs.FlushFinalBlock();
- cipherBytes = ms.ToArray();//得到加密后的字节数组
- cs.Close();
- ms.Close();
- }
- }
- return Convert.ToBase64String(cipherBytes);
- }
- catch { }
- return str;
- }
- /// <summary>
- /// AES解密
- /// </summary>
- /// <param name="str">待解密字符串</param>
- /// <returns>解密后字符串</returns>
- public static string DecryptAES(string str, string key)
- {
- try
- {
- byte[] cipherText = Convert.FromBase64String(str);
- AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
- aes.Key = Encoding.UTF8.GetBytes(key);
- //aes.IV = Encoding.UTF8.GetBytes(key);
- aes.Mode = CipherMode.ECB;
- aes.Padding = PaddingMode.PKCS7;
- byte[] decryptBytes = new byte[cipherText.Length];
- using (MemoryStream ms = new MemoryStream(cipherText))
- {
- using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read))
- {
- cs.Read(decryptBytes, 0, decryptBytes.Length);
- cs.Close();
- ms.Close();
- }
- }
- return Encoding.UTF8.GetString(decryptBytes).Replace("\0", ""); //将字符串后尾的'\0'去掉
- }
- catch { }
- return str;
- }
- #endregion
- }
- }
|