From 299d03bdb063e682c93bb5dd102fccd0adb090c2 Mon Sep 17 00:00:00 2001 From: ky_sunl Date: Wed, 17 Mar 2021 08:51:06 +0000 Subject: [PATCH] --- .../Authorized/AuthorizedHelper.cs | 205 ++++++++++++++ .../Authorized/AuthorizedWhiteListHelper.cs | 249 ++++++++++++++++++ .../Authorized/WhiteListToken.cs | 17 ++ .../Ewide.Core.Common.csproj | 28 ++ Api/Ewide.Core/Ewide.Core.Common/app.config | 15 ++ .../Ewide.Core.Common/packages.config | 4 + .../Ewide.Core.Data/DapperHelper.cs | 34 +-- Api/Ewide.Core/Ewide.Core.Model/EC_User.cs | 14 + .../Ewide.Core.Model/Ewide.Core.Model.csproj | 1 + .../Ewide.Core.Service.csproj | 12 + .../Controllers/Code/BaseController.cs | 2 +- .../Controllers/GateController.cs | 21 +- .../Ewide.Core.WebApi.csproj | 4 - Api/Ewide.Core/Ewide.Core.WebApi/Web.config | 2 +- 14 files changed, 566 insertions(+), 42 deletions(-) create mode 100644 Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedHelper.cs create mode 100644 Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedWhiteListHelper.cs create mode 100644 Api/Ewide.Core/Ewide.Core.Common/Authorized/WhiteListToken.cs create mode 100644 Api/Ewide.Core/Ewide.Core.Common/app.config create mode 100644 Api/Ewide.Core/Ewide.Core.Model/EC_User.cs diff --git a/Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedHelper.cs b/Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedHelper.cs new file mode 100644 index 0000000..9ea2811 --- /dev/null +++ b/Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedHelper.cs @@ -0,0 +1,205 @@ +using Ewide.Core.Model; +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Ewide.Core.Common +{ + public class AuthorizedHelper : AuthorizedWhiteListHelper + { + private static readonly string JWT_Secret = System.Configuration.ConfigurationManager.ConnectionStrings["Token_JwtSecret"]?.ToString(); + + private static readonly string JWT_User = System.Configuration.ConfigurationManager.ConnectionStrings["Token_JwtUser"]?.ToString(); + + private static readonly string WhiteList_Key = System.Configuration.ConfigurationManager.ConnectionStrings["Token_WhiteList"]?.ToString(); + + /// + /// 从Request中获取Token值。 + /// + public static string RequestToken + { + get + { + var authorization = HttpContext.Current.Request.Headers["Authorization"]; + if (String.IsNullOrEmpty(authorization)) + { + return null; + } + var token = authorization.Split(' '); + if (token.Length == 2) + { + return token.Last(); + } + return null; + } + } + + /// + /// 用户ID。 + /// + public static string CurrentUserID + { + get + { + return GetUserID(); + } + } + + /// + /// 用户信息。 + /// + public static EC_User CurrentUser + { + get + { + var userID = CurrentUserID; + if (String.IsNullOrEmpty(userID)) + { + return null; + } + var user = GetWhiteListUser(userID); + return user; + } + } + + /// + /// 将字符串转成JwtToken类型,并指示是否转换成功。 + /// + /// + /// + /// + public static bool TryParseToken(string token, out JwtSecurityToken t) + { + t = null; + if (String.IsNullOrWhiteSpace(token)) + { + return false; + } + var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_Secret)); + try + { + var vResult = new JwtSecurityTokenHandler().ValidateToken(token, new TokenValidationParameters() + { + ValidIssuer = JWT_User, + ValidateIssuer = true, + ValidateAudience = false, + IssuerSigningKey = symmetricSecurityKey + }, out SecurityToken securityToken); + t = (JwtSecurityToken)securityToken; + return true; + } + catch + { + return false; + } + } + + /// + /// 绕过白名单检测,直接通过Token来读取用户ID。 + /// + /// + /// + public static string GetUserIDFromToken(string token) + { + if (TryParseToken(token, out JwtSecurityToken jwtSecurityToken)) + { + var userID = jwtSecurityToken.Payload["UserID"]?.ToString(); + return userID; + } + return null; + } + + /// + /// 通过在白名单中的Token来读取用户ID。 + /// + /// + /// + public static string GetUserID(string token) + { + if (CheckWhiteList(token)) + { + return GetUserIDFromToken(token); + } + return null; + } + + /// + /// 读取用户ID。 + /// + /// + public static string GetUserID() + { + return GetUserID(RequestToken); + } + + /// + /// 新建Token并添加到白名单。 + /// + /// + /// + public static string AddToken(EC_User user) + { + var claims = new Claim[] + { + new Claim("UserID", user.ID), + new Claim("UserName", user.Account), + }; + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_Secret)); + var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + var now = DateTime.UtcNow; + var token = new JwtSecurityToken( + JWT_User, + user.ID, + claims, + now, + now.AddDays(30), + creds); + var tokenString = new JwtSecurityTokenHandler().WriteToken(token); + + AddWhiteList(tokenString); + + return tokenString; + } + + /// + /// 从白名单中删除Token。 + /// + public static void RemoveToken() + { + RemoveWhiteList(RequestToken); + } + + /// + /// 通过用户ID从白名单中删除Token。 + /// + /// + public static void RemoveTokenByUserID(string userID) + { + RemoveWhiteListByUserID(userID); + } + + /// + /// 在白名单中更新用户信息。 + /// + /// + public static void UpdateCacheUser(EC_User user) + { + UpdateWhiteListUser(user); + } + + /// + /// 通过用户ID在白名单中更新用户信息。 + /// + /// + public static void UpdateCacheUser(string userID) + { + UpdateWhiteListUser(userID); + } + } +} diff --git a/Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedWhiteListHelper.cs b/Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedWhiteListHelper.cs new file mode 100644 index 0000000..6ed4c55 --- /dev/null +++ b/Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedWhiteListHelper.cs @@ -0,0 +1,249 @@ +using DapperExtensions; +using Ewide.Core.Data; +using Ewide.Core.Model; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Ewide.Core.Common +{ + public class AuthorizedWhiteListHelper + { + private static readonly string WhiteList_Key = System.Configuration.ConfigurationManager.ConnectionStrings["Token_WhiteList"]?.ToString(); + + private static readonly string CachePath = HttpContext.Current.Server.MapPath("\\" + Path.Combine("Cache", WhiteList_Key + ".bin")); + + /// + /// Token白名单 + /// + private static List WhiteList + { +#if DEBUG + get + { + var list = (List)HttpRuntime.Cache.Get(WhiteList_Key); + + if (list == null) + { + if (!File.Exists(CachePath)) + { + return null; + } + + var fs = new FileStream(CachePath, FileMode.Open); + var reader = new StreamReader(fs); + list = Newtonsoft.Json.JsonConvert.DeserializeObject>(reader.ReadToEnd()); + reader.Close(); + fs.Close(); + HttpRuntime.Cache.Insert(WhiteList_Key, list); + return list; + } + + return list; + } + set + { + if (!Directory.Exists(Path.GetDirectoryName(CachePath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(CachePath)); + } + if (!File.Exists(CachePath)) + { + File.Create(CachePath).Close(); + } + var sw = new StreamWriter(CachePath, false, Encoding.UTF8); + sw.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(value)); + sw.Close(); + + HttpRuntime.Cache.Insert(WhiteList_Key, value); + } +#else + get + { + return (List)HttpRuntime.Cache.Get(WhiteList_Key); + } + set + { + HttpRuntime.Cache.Insert(WhiteList_Key, value, null, DateTime.Now.AddDays(30), TimeSpan.Zero); + } +#endif + } + + /// + /// 根据UserID获取白名单信息 + /// + /// + /// + protected static WhiteListToken GetWhiteListByUserID(string userID) + { + var list = WhiteList; + if (list == null) + { + return null; + } + var item = list.FirstOrDefault(p => p.UserID.Equals(userID, StringComparison.CurrentCultureIgnoreCase)); + return item; + } + + /// + /// 从Token白名单中删除 + /// + /// + protected static void RemoveWhiteList(string token) + { + var userID = AuthorizedHelper.GetUserIDFromToken(token); + RemoveWhiteListByUserID(userID); + } + + /// + /// 根据UserID删除白名单 + /// + /// + protected static void RemoveWhiteListByUserID(string userID) + { + var list = WhiteList; + if (list != null) + { + var item = list.FirstOrDefault(p => p.UserID.Equals(userID, StringComparison.CurrentCultureIgnoreCase)); + if (item != null) + { + list.Remove(item); + WhiteList = list; + } + } + } + + /// + /// 添加到Token白名单 + /// + /// + protected static void AddWhiteList(string token) + { + var list = WhiteList; + var userID = AuthorizedHelper.GetUserIDFromToken(token); + using (var db = new DapperHelper()) + { + var user = db.Conn.Get(userID); + var exp = DateTime.Now.AddDays(30); + if (list == null) + { + list = new List + { + new WhiteListToken + { + UserID = userID, + User = user, + Token = token, + ExpDate = exp + } + }; + } + else + { + var item = list.FirstOrDefault(p => p.UserID.Equals(userID, StringComparison.CurrentCultureIgnoreCase)); + if (item != null) + { + item.Token = token; + item.ExpDate = exp; + } + else + { + list.Add(new WhiteListToken + { + UserID = userID, + User = user, + Token = token, + ExpDate = exp + }); + } + } + } + WhiteList = list; + } + + /// + /// 根据UserID获取白名单中的用户信息 + /// + /// + /// + protected static EC_User GetWhiteListUser(string userID) + { + var item = GetWhiteListByUserID(userID); + if (item == null) + { + return null; + } + + return item.User; + } + + /// + /// 更新白名单中的用户信息 + /// + /// + protected static void UpdateWhiteListUser(string userID) + { + using (var db = new DapperHelper()) + { + var user = db.Conn.Get(userID); + if (user == null) + { + return; + } + UpdateWhiteListUser(user); + } + } + + /// + /// 更新白名单中的用户信息 + /// + /// + protected static void UpdateWhiteListUser(EC_User user) + { + var list = WhiteList; + if (list == null) + { + return; + } + var item = list.FirstOrDefault(p => p.UserID.Equals(user.ID, StringComparison.CurrentCultureIgnoreCase)); + if (item == null) + { + return; + } + item.User = user; + WhiteList = list; + } + + /// + /// + /// + /// + /// + protected static bool CheckWhiteList(string token) + { + var list = WhiteList; + if (list == null) + { + return false; + } + var item = list.FirstOrDefault(p => p.Token.Equals(token)); + if (item != null) + { + if (item.ExpDate > DateTime.Now) + { + return true; + } + else + { + list.Remove(item); + WhiteList = list; + } + } + return false; + } + } +} diff --git a/Api/Ewide.Core/Ewide.Core.Common/Authorized/WhiteListToken.cs b/Api/Ewide.Core/Ewide.Core.Common/Authorized/WhiteListToken.cs new file mode 100644 index 0000000..2b34a6b --- /dev/null +++ b/Api/Ewide.Core/Ewide.Core.Common/Authorized/WhiteListToken.cs @@ -0,0 +1,17 @@ +using Ewide.Core.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ewide.Core.Common +{ + public class WhiteListToken + { + public string UserID { get; set; } + public EC_User User { get; set; } + public string Token { get; set; } + public DateTime ExpDate { get; set; } + } +} diff --git a/Api/Ewide.Core/Ewide.Core.Common/Ewide.Core.Common.csproj b/Api/Ewide.Core/Ewide.Core.Common/Ewide.Core.Common.csproj index ccfecec..bb47bea 100644 --- a/Api/Ewide.Core/Ewide.Core.Common/Ewide.Core.Common.csproj +++ b/Api/Ewide.Core/Ewide.Core.Common/Ewide.Core.Common.csproj @@ -32,11 +32,25 @@ 4 + + ..\packages\Microsoft.IdentityModel.JsonWebTokens.6.9.0\lib\net45\Microsoft.IdentityModel.JsonWebTokens.dll + + + ..\packages\Microsoft.IdentityModel.Logging.6.9.0\lib\net45\Microsoft.IdentityModel.Logging.dll + + + ..\packages\Microsoft.IdentityModel.Tokens.6.9.0\lib\net45\Microsoft.IdentityModel.Tokens.dll + ..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\System.IdentityModel.Tokens.Jwt.6.9.0\lib\net45\System.IdentityModel.Tokens.Jwt.dll + + @@ -45,6 +59,9 @@ + + + @@ -52,7 +69,18 @@ + + + + {b5b46bad-81e3-4df0-83ef-75148236f7ce} + Ewide.Core.Data + + + {31C3CA3D-14A1-453A-866D-76D4C74A9BDC} + Ewide.Core.Model + + \ No newline at end of file diff --git a/Api/Ewide.Core/Ewide.Core.Common/app.config b/Api/Ewide.Core/Ewide.Core.Common/app.config new file mode 100644 index 0000000..e55ecdf --- /dev/null +++ b/Api/Ewide.Core/Ewide.Core.Common/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Api/Ewide.Core/Ewide.Core.Common/packages.config b/Api/Ewide.Core/Ewide.Core.Common/packages.config index f7c9995..8be348f 100644 --- a/Api/Ewide.Core/Ewide.Core.Common/packages.config +++ b/Api/Ewide.Core/Ewide.Core.Common/packages.config @@ -1,4 +1,8 @@  + + + + \ No newline at end of file diff --git a/Api/Ewide.Core/Ewide.Core.Data/DapperHelper.cs b/Api/Ewide.Core/Ewide.Core.Data/DapperHelper.cs index 948ddfc..7640940 100644 --- a/Api/Ewide.Core/Ewide.Core.Data/DapperHelper.cs +++ b/Api/Ewide.Core/Ewide.Core.Data/DapperHelper.cs @@ -10,52 +10,52 @@ namespace Ewide.Core.Data { public class DapperHelper : IDisposable { - private readonly static string _connString = System.Configuration.ConfigurationManager.ConnectionStrings["MySqlConnection"].ToString(); + private readonly static string _connString = System.Configuration.ConfigurationManager.ConnectionStrings["MySqlConnection"]?.ToString(); - public IDbConnection Sql = null; + public IDbConnection Conn { get; } = null; public DapperHelper() { - Sql = new MySqlConnection(_connString); - if (Sql.State == ConnectionState.Closed) + Conn = new MySqlConnection(_connString); + if (Conn.State == ConnectionState.Closed) { - Sql.Open(); + Conn.Open(); } } void IDisposable.Dispose() { - if (Sql.State == ConnectionState.Open) + if (Conn.State == ConnectionState.Open) { - Sql.Close(); + Conn.Close(); } - Sql.Dispose(); + Conn.Dispose(); } } public class DapperTransactionHelper : IDisposable { - private readonly static string _connString = System.Configuration.ConfigurationManager.ConnectionStrings["MySqlConnection"].ToString(); + private readonly static string _connString = System.Configuration.ConfigurationManager.ConnectionStrings["MySqlConnection"]?.ToString(); - public IDbConnection Sql = null; + public IDbConnection Conn { get; } = null; private IDbTransaction _trans = null; public DapperTransactionHelper() { - Sql = new MySqlConnection(_connString); - if (Sql.State == ConnectionState.Closed) + Conn = new MySqlConnection(_connString); + if (Conn.State == ConnectionState.Closed) { - Sql.Open(); + Conn.Open(); } - _trans = Sql.BeginTransaction(); + _trans = Conn.BeginTransaction(); } private void Close() { - if (Sql.State == ConnectionState.Open) + if (Conn.State == ConnectionState.Open) { - Sql.Close(); + Conn.Close(); } } @@ -63,7 +63,7 @@ namespace Ewide.Core.Data { _trans.Dispose(); this.Close(); - Sql.Dispose(); + Conn.Dispose(); } public void Complete() diff --git a/Api/Ewide.Core/Ewide.Core.Model/EC_User.cs b/Api/Ewide.Core/Ewide.Core.Model/EC_User.cs new file mode 100644 index 0000000..ecc5884 --- /dev/null +++ b/Api/Ewide.Core/Ewide.Core.Model/EC_User.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ewide.Core.Model +{ + public class EC_User + { + public string ID { get; set; } + public string Account { get; set; } + } +} diff --git a/Api/Ewide.Core/Ewide.Core.Model/Ewide.Core.Model.csproj b/Api/Ewide.Core/Ewide.Core.Model/Ewide.Core.Model.csproj index dab9953..817b345 100644 --- a/Api/Ewide.Core/Ewide.Core.Model/Ewide.Core.Model.csproj +++ b/Api/Ewide.Core/Ewide.Core.Model/Ewide.Core.Model.csproj @@ -54,6 +54,7 @@ + diff --git a/Api/Ewide.Core/Ewide.Core.Service/Ewide.Core.Service.csproj b/Api/Ewide.Core/Ewide.Core.Service/Ewide.Core.Service.csproj index dc47421..89b474d 100644 --- a/Api/Ewide.Core/Ewide.Core.Service/Ewide.Core.Service.csproj +++ b/Api/Ewide.Core/Ewide.Core.Service/Ewide.Core.Service.csproj @@ -45,6 +45,18 @@ + + {9003b29c-ac1d-444e-8fe2-201f76d848a5} + Ewide.Core.DTO + + + {c7e2ac14-ac20-4552-a5b8-08b650ac8416} + Ewide.Core.Common + + + {b5b46bad-81e3-4df0-83ef-75148236f7ce} + Ewide.Core.Data + {31c3ca3d-14a1-453a-866d-76d4c74a9bdc} Ewide.Core.Model diff --git a/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/Code/BaseController.cs b/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/Code/BaseController.cs index 72f7d3a..58e98f1 100644 --- a/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/Code/BaseController.cs +++ b/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/Code/BaseController.cs @@ -15,7 +15,7 @@ namespace Ewide.Core.WebApi { protected override void Initialize(HttpControllerContext controllerContext) { - base.Initialize(controllerContext); + //base.Initialize(controllerContext); } protected override ExceptionResult InternalServerError(Exception exception) diff --git a/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/GateController.cs b/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/GateController.cs index 1a15d7e..597a349 100644 --- a/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/GateController.cs +++ b/Api/Ewide.Core/Ewide.Core.WebApi/Controllers/GateController.cs @@ -1,5 +1,4 @@ -using Dapper; -using Ewide.Core.DTO; +using Ewide.Core.DTO; using System; using System.Collections.Generic; using System.Diagnostics; @@ -15,23 +14,7 @@ namespace Ewide.Core.WebApi.Controllers { public IHttpActionResult Login(TestArgs A) { - using (var db = new Data.DapperHelper()) - { - var sw = new Stopwatch(); - sw.Start(); - db.Sql.Query("SELECT * FROM nbhudb_zzfwzxx").ToList(); - sw.Stop(); - var t1 = sw.Elapsed.Milliseconds; - sw.Restart(); - db.Sql.Query("SELECT * FROM nbhudb_zzfwzxx limit 3000,10"); - sw.Stop(); - var t2 = sw.Elapsed.Milliseconds; - return DisplayJSON(new - { - t1, - t2 - }); - } + return DisplayJSON(""); } } } diff --git a/Api/Ewide.Core/Ewide.Core.WebApi/Ewide.Core.WebApi.csproj b/Api/Ewide.Core/Ewide.Core.WebApi/Ewide.Core.WebApi.csproj index d54640c..a0153ac 100644 --- a/Api/Ewide.Core/Ewide.Core.WebApi/Ewide.Core.WebApi.csproj +++ b/Api/Ewide.Core/Ewide.Core.WebApi/Ewide.Core.WebApi.csproj @@ -261,10 +261,6 @@ {c7e2ac14-ac20-4552-a5b8-08b650ac8416} Ewide.Core.Common - - {b5b46bad-81e3-4df0-83ef-75148236f7ce} - Ewide.Core.Data - {34ae80c2-5c37-4b6c-aac3-f52c06928721} Ewide.Core.Service diff --git a/Api/Ewide.Core/Ewide.Core.WebApi/Web.config b/Api/Ewide.Core/Ewide.Core.WebApi/Web.config index 265ce45..a0fc5f7 100644 --- a/Api/Ewide.Core/Ewide.Core.WebApi/Web.config +++ b/Api/Ewide.Core/Ewide.Core.WebApi/Web.config @@ -5,7 +5,7 @@ --> - +