This commit is contained in:
ky_sunl
2021-03-17 08:51:06 +00:00
parent 1688c9f8d1
commit 299d03bdb0
14 changed files with 566 additions and 42 deletions

View File

@@ -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();
/// <summary>
/// 从Request中获取Token值。
/// </summary>
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;
}
}
/// <summary>
/// 用户ID。
/// </summary>
public static string CurrentUserID
{
get
{
return GetUserID();
}
}
/// <summary>
/// 用户信息。
/// </summary>
public static EC_User CurrentUser
{
get
{
var userID = CurrentUserID;
if (String.IsNullOrEmpty(userID))
{
return null;
}
var user = GetWhiteListUser(userID);
return user;
}
}
/// <summary>
/// 将字符串转成JwtToken类型并指示是否转换成功。
/// </summary>
/// <param name="token"></param>
/// <param name="t"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 绕过白名单检测直接通过Token来读取用户ID。
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public static string GetUserIDFromToken(string token)
{
if (TryParseToken(token, out JwtSecurityToken jwtSecurityToken))
{
var userID = jwtSecurityToken.Payload["UserID"]?.ToString();
return userID;
}
return null;
}
/// <summary>
/// 通过在白名单中的Token来读取用户ID。
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public static string GetUserID(string token)
{
if (CheckWhiteList(token))
{
return GetUserIDFromToken(token);
}
return null;
}
/// <summary>
/// 读取用户ID。
/// </summary>
/// <returns></returns>
public static string GetUserID()
{
return GetUserID(RequestToken);
}
/// <summary>
/// 新建Token并添加到白名单。
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 从白名单中删除Token。
/// </summary>
public static void RemoveToken()
{
RemoveWhiteList(RequestToken);
}
/// <summary>
/// 通过用户ID从白名单中删除Token。
/// </summary>
/// <param name="userID"></param>
public static void RemoveTokenByUserID(string userID)
{
RemoveWhiteListByUserID(userID);
}
/// <summary>
/// 在白名单中更新用户信息。
/// </summary>
/// <param name="user"></param>
public static void UpdateCacheUser(EC_User user)
{
UpdateWhiteListUser(user);
}
/// <summary>
/// 通过用户ID在白名单中更新用户信息。
/// </summary>
/// <param name="userID"></param>
public static void UpdateCacheUser(string userID)
{
UpdateWhiteListUser(userID);
}
}
}

View File

@@ -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"));
/// <summary>
/// Token白名单
/// </summary>
private static List<WhiteListToken> WhiteList
{
#if DEBUG
get
{
var list = (List<WhiteListToken>)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<List<WhiteListToken>>(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<WhiteListToken>)HttpRuntime.Cache.Get(WhiteList_Key);
}
set
{
HttpRuntime.Cache.Insert(WhiteList_Key, value, null, DateTime.Now.AddDays(30), TimeSpan.Zero);
}
#endif
}
/// <summary>
/// 根据UserID获取白名单信息
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 从Token白名单中删除
/// </summary>
/// <param name="token"></param>
protected static void RemoveWhiteList(string token)
{
var userID = AuthorizedHelper.GetUserIDFromToken(token);
RemoveWhiteListByUserID(userID);
}
/// <summary>
/// 根据UserID删除白名单
/// </summary>
/// <param name="userID"></param>
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;
}
}
}
/// <summary>
/// 添加到Token白名单
/// </summary>
/// <param name="token"></param>
protected static void AddWhiteList(string token)
{
var list = WhiteList;
var userID = AuthorizedHelper.GetUserIDFromToken(token);
using (var db = new DapperHelper())
{
var user = db.Conn.Get<EC_User>(userID);
var exp = DateTime.Now.AddDays(30);
if (list == null)
{
list = new List<WhiteListToken>
{
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;
}
/// <summary>
/// 根据UserID获取白名单中的用户信息
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
protected static EC_User GetWhiteListUser(string userID)
{
var item = GetWhiteListByUserID(userID);
if (item == null)
{
return null;
}
return item.User;
}
/// <summary>
/// 更新白名单中的用户信息
/// </summary>
/// <param name="userID"></param>
protected static void UpdateWhiteListUser(string userID)
{
using (var db = new DapperHelper())
{
var user = db.Conn.Get<EC_User>(userID);
if (user == null)
{
return;
}
UpdateWhiteListUser(user);
}
}
/// <summary>
/// 更新白名单中的用户信息
/// </summary>
/// <param name="user"></param>
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;
}
/// <summary>
///
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
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;
}
}
}

View File

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

View File

@@ -32,11 +32,25 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.IdentityModel.JsonWebTokens, Version=6.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.JsonWebTokens.6.9.0\lib\net45\Microsoft.IdentityModel.JsonWebTokens.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Logging, Version=6.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Logging.6.9.0\lib\net45\Microsoft.IdentityModel.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Tokens, Version=6.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Tokens.6.9.0\lib\net45\Microsoft.IdentityModel.Tokens.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=6.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\System.IdentityModel.Tokens.Jwt.6.9.0\lib\net45\System.IdentityModel.Tokens.Jwt.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@@ -45,6 +59,9 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Authorized\AuthorizedHelper.cs" />
<Compile Include="Authorized\AuthorizedWhiteListHelper.cs" />
<Compile Include="Authorized\WhiteListToken.cs" />
<Compile Include="BaseDisplayJSON.cs" /> <Compile Include="BaseDisplayJSON.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
@@ -52,7 +69,18 @@
<Folder Include="EnumCode\" /> <Folder Include="EnumCode\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ewide.Core.Data\Ewide.Core.Data.csproj">
<Project>{b5b46bad-81e3-4df0-83ef-75148236f7ce}</Project>
<Name>Ewide.Core.Data</Name>
</ProjectReference>
<ProjectReference Include="..\Ewide.Core.Model\Ewide.Core.Model.csproj">
<Project>{31C3CA3D-14A1-453A-866D-76D4C74A9BDC}</Project>
<Name>Ewide.Core.Model</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -1,4 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Microsoft.IdentityModel.JsonWebTokens" version="6.9.0" targetFramework="net452" />
<package id="Microsoft.IdentityModel.Logging" version="6.9.0" targetFramework="net452" />
<package id="Microsoft.IdentityModel.Tokens" version="6.9.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="11.0.1" targetFramework="net45" /> <package id="Newtonsoft.Json" version="11.0.1" targetFramework="net45" />
<package id="System.IdentityModel.Tokens.Jwt" version="6.9.0" targetFramework="net452" />
</packages> </packages>

View File

@@ -10,52 +10,52 @@ namespace Ewide.Core.Data
{ {
public class DapperHelper : IDisposable 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() public DapperHelper()
{ {
Sql = new MySqlConnection(_connString); Conn = new MySqlConnection(_connString);
if (Sql.State == ConnectionState.Closed) if (Conn.State == ConnectionState.Closed)
{ {
Sql.Open(); Conn.Open();
} }
} }
void IDisposable.Dispose() 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 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; private IDbTransaction _trans = null;
public DapperTransactionHelper() public DapperTransactionHelper()
{ {
Sql = new MySqlConnection(_connString); Conn = new MySqlConnection(_connString);
if (Sql.State == ConnectionState.Closed) if (Conn.State == ConnectionState.Closed)
{ {
Sql.Open(); Conn.Open();
} }
_trans = Sql.BeginTransaction(); _trans = Conn.BeginTransaction();
} }
private void Close() 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(); _trans.Dispose();
this.Close(); this.Close();
Sql.Dispose(); Conn.Dispose();
} }
public void Complete() public void Complete()

View File

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

View File

@@ -54,6 +54,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="EC_User.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -45,6 +45,18 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Ewide.Core.Arguments\Ewide.Core.DTO.csproj">
<Project>{9003b29c-ac1d-444e-8fe2-201f76d848a5}</Project>
<Name>Ewide.Core.DTO</Name>
</ProjectReference>
<ProjectReference Include="..\Ewide.Core.Common\Ewide.Core.Common.csproj">
<Project>{c7e2ac14-ac20-4552-a5b8-08b650ac8416}</Project>
<Name>Ewide.Core.Common</Name>
</ProjectReference>
<ProjectReference Include="..\Ewide.Core.Data\Ewide.Core.Data.csproj">
<Project>{b5b46bad-81e3-4df0-83ef-75148236f7ce}</Project>
<Name>Ewide.Core.Data</Name>
</ProjectReference>
<ProjectReference Include="..\Ewide.Core.Model\Ewide.Core.Model.csproj"> <ProjectReference Include="..\Ewide.Core.Model\Ewide.Core.Model.csproj">
<Project>{31c3ca3d-14a1-453a-866d-76d4c74a9bdc}</Project> <Project>{31c3ca3d-14a1-453a-866d-76d4c74a9bdc}</Project>
<Name>Ewide.Core.Model</Name> <Name>Ewide.Core.Model</Name>

View File

@@ -15,7 +15,7 @@ namespace Ewide.Core.WebApi
{ {
protected override void Initialize(HttpControllerContext controllerContext) protected override void Initialize(HttpControllerContext controllerContext)
{ {
base.Initialize(controllerContext); //base.Initialize(controllerContext);
} }
protected override ExceptionResult InternalServerError(Exception exception) protected override ExceptionResult InternalServerError(Exception exception)

View File

@@ -1,5 +1,4 @@
using Dapper; using Ewide.Core.DTO;
using Ewide.Core.DTO;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@@ -15,23 +14,7 @@ namespace Ewide.Core.WebApi.Controllers
{ {
public IHttpActionResult Login(TestArgs A) public IHttpActionResult Login(TestArgs A)
{ {
using (var db = new Data.DapperHelper()) return DisplayJSON("");
{
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
});
}
} }
} }
} }

View File

@@ -261,10 +261,6 @@
<Project>{c7e2ac14-ac20-4552-a5b8-08b650ac8416}</Project> <Project>{c7e2ac14-ac20-4552-a5b8-08b650ac8416}</Project>
<Name>Ewide.Core.Common</Name> <Name>Ewide.Core.Common</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Ewide.Core.Data\Ewide.Core.Data.csproj">
<Project>{b5b46bad-81e3-4df0-83ef-75148236f7ce}</Project>
<Name>Ewide.Core.Data</Name>
</ProjectReference>
<ProjectReference Include="..\Ewide.Core.Service\Ewide.Core.Service.csproj"> <ProjectReference Include="..\Ewide.Core.Service\Ewide.Core.Service.csproj">
<Project>{34ae80c2-5c37-4b6c-aac3-f52c06928721}</Project> <Project>{34ae80c2-5c37-4b6c-aac3-f52c06928721}</Project>
<Name>Ewide.Core.Service</Name> <Name>Ewide.Core.Service</Name>

View File

@@ -5,7 +5,7 @@
--> -->
<configuration> <configuration>
<connectionStrings> <connectionStrings>
<add name="MySqlConnection" connectionString="server=localhost;user id=root;password=a45683926;database=test;persistsecurityinfo=True" /> <add name="MySqlConnection" connectionString="server=localhost;user id=root;password=a45683926;database=ewide.core;persistsecurityinfo=True" />
</connectionStrings> </connectionStrings>
<appSettings> <appSettings>
<add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Version" value="3.0.0.0" />