This commit is contained in:
205
Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedHelper.cs
Normal file
205
Api/Ewide.Core/Ewide.Core.Common/Authorized/AuthorizedHelper.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -32,11 +32,25 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<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">
|
||||
<HintPath>..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<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.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@@ -45,6 +59,9 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Authorized\AuthorizedHelper.cs" />
|
||||
<Compile Include="Authorized\AuthorizedWhiteListHelper.cs" />
|
||||
<Compile Include="Authorized\WhiteListToken.cs" />
|
||||
<Compile Include="BaseDisplayJSON.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
@@ -52,7 +69,18 @@
|
||||
<Folder Include="EnumCode\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</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" />
|
||||
</Project>
|
||||
15
Api/Ewide.Core/Ewide.Core.Common/app.config
Normal file
15
Api/Ewide.Core/Ewide.Core.Common/app.config
Normal 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>
|
||||
@@ -1,4 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="System.IdentityModel.Tokens.Jwt" version="6.9.0" targetFramework="net452" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user