ow
This commit is contained in:
1 parent
31fbe199c1
commit
1c0c83af5f
469 files changed
+62544
-5
No files matched your search
@@ -0,0 +1,488 @@
|
||||
using Azure.Core;
|
||||
using CloudBuilder.Core.Authorization;
|
||||
using CloudBuilder.Core.DatabaseAccessor;
|
||||
using CloudBuilder.Core.DatabaseAccessor.Entity;
|
||||
using CloudBuilder.Core.DependencyInjection.EventBuses;
|
||||
using CloudBuilder.Core.DependencyInjection.Request;
|
||||
using CloudBuilder.Core.Policy;
|
||||
using CloudBuilder.Core.Service;
|
||||
using CloudBuilder.Security.Data;
|
||||
using CloudBuilder.Security.Entity;
|
||||
using CloudBuilder.Security.Policy;
|
||||
using CloudBuilder.Security.Publisher;
|
||||
using CloudBuilder.Security.Service.Authorization;
|
||||
using CloudBuilder.Security.Service.Publisher;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.JsonWebTokens;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Runtime;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace CloudBuilder.Security.Service
|
||||
{
|
||||
public class AuthService : IAuthService
|
||||
{
|
||||
private readonly IApplicationService service;
|
||||
private readonly IHttpContextAccessor httpContextAccessor;
|
||||
private readonly ILocaleMessageManager localeMessageManager;
|
||||
private readonly IContext context;
|
||||
private IRepository<SecurityUserEntity> repository;
|
||||
public AuthService(IApplicationService service, IHttpContextAccessor httpContextAccessor, ILocaleMessageManager localeMessageManager, IContext context)
|
||||
{
|
||||
this.service = service;
|
||||
this.httpContextAccessor = httpContextAccessor;
|
||||
this.localeMessageManager = localeMessageManager;
|
||||
this.context = context;
|
||||
repository = service.GetRepository<IRepository<SecurityUserEntity>>();
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[UnitOfWork]
|
||||
public LoginProfile Login(LoginData data)
|
||||
{
|
||||
context.SetCulture(data.Culture);
|
||||
string certification = localeMessageManager.ComposeMessage(typeof(AuthService).Name, "certification");
|
||||
SecurityUserEntity securityUserEntity = repository.DetachedEntities.Where(x =>
|
||||
(x.UserName == data.UserMobile || x.UserMobile == data.UserMobile)
|
||||
&& x.UserIsValidIndc == YesNoPolicy.YES).FirstOrDefault()!;
|
||||
|
||||
if (securityUserEntity == null)
|
||||
{
|
||||
throw new ValidatedException(certification);
|
||||
}
|
||||
|
||||
var descKey = service.Configuration[SecuritySettingsPolicy.SecuritySettings_DescKey];
|
||||
|
||||
var privateKey = service.Configuration[SecuritySettingsPolicy.SecuritySettings_RsaPrivateKey];
|
||||
var rsa = new RSA(privateKey, true);
|
||||
|
||||
var psd = rsa.DecodeOrNull(data.RsaUserPassword);
|
||||
if (string.IsNullOrEmpty(psd)) throw new ValidatedException(certification);
|
||||
//052636a8-b146-9efd-f5dc-0034a3c5bb34+password
|
||||
var guid = psd.Substring(0, 36);
|
||||
|
||||
|
||||
if (guid != data.Guid)
|
||||
{
|
||||
throw new ValidatedException(certification);
|
||||
}
|
||||
|
||||
if (securityUserEntity.IsAccountsLockedIndc == YesNoPolicy.YES && securityUserEntity.AccountsLockedDatetime.HasValue
|
||||
&& securityUserEntity.AccountsLockedDatetime.Value.Subtract(DateTime.Now).TotalMinutes > 0)
|
||||
{
|
||||
throw new ValidatedException(localeMessageManager.ComposeMessage("AuthService", "locked"));
|
||||
}
|
||||
|
||||
data.UserPassword = psd.Substring(36, psd.Length - 36);
|
||||
|
||||
if (securityUserEntity.UserPassword != data.UserPassword)
|
||||
{
|
||||
securityUserEntity.ErrorLoginCount += 1;
|
||||
//输错多少次后,账号锁定
|
||||
if (securityUserEntity.ErrorLoginCount > SecurityUserPolicy.ERROR_LOGIN_COUNT)
|
||||
{
|
||||
securityUserEntity.IsAccountsLockedIndc = YesNoPolicy.YES;
|
||||
securityUserEntity.AccountsLockedDatetime = DateTime.Now.AddDays(1);
|
||||
}
|
||||
|
||||
repository.UpdateNow(securityUserEntity);
|
||||
|
||||
throw new ValidatedException(certification);
|
||||
}
|
||||
|
||||
JwtGenerate jwtGenerate = service.ServiceProvider.GetService<JwtGenerate>()!;
|
||||
|
||||
string clainmName = Guid.NewGuid().ToString();
|
||||
Dictionary<string, string> claims = new Dictionary<string, string>();
|
||||
claims.Add(ClaimPolicy.CLAINM_NAME, clainmName);
|
||||
claims.Add(ClaimPolicy.CLAINM_ACCOUNT, securityUserEntity.UserMobile!);
|
||||
claims.Add(ClaimPolicy.CLAINM_USERID, securityUserEntity.UserName);
|
||||
claims.Add(ClaimPolicy.CLAINM_LOCALE, data.Culture);
|
||||
|
||||
var accessToken = jwtGenerate.Generate(claims);
|
||||
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
httpContextAccessor.HttpContext.Request.Headers.Remove("Authorization");
|
||||
httpContextAccessor.HttpContext.Request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
|
||||
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey(ClaimPolicy.HEADER_LOCALE))
|
||||
httpContextAccessor.HttpContext.Request.Headers.Remove(ClaimPolicy.HEADER_LOCALE);
|
||||
httpContextAccessor.HttpContext.Request.Headers.Add(ClaimPolicy.HEADER_LOCALE, data.Culture);
|
||||
|
||||
service.UserId = securityUserEntity.UserName;
|
||||
|
||||
securityUserEntity.ErrorLoginCount = 0;
|
||||
securityUserEntity.IsAccountsLockedIndc = YesNoPolicy.NO;
|
||||
securityUserEntity.AccountsLockedDatetime = null;
|
||||
//更新最后登录日期
|
||||
securityUserEntity.LastLoginDatetime = DateTime.Now;
|
||||
|
||||
repository.UpdateNow(securityUserEntity);
|
||||
|
||||
IRepository<SecurityUserWebLoginEntity> repositoryLog = service.GetRepository<IRepository<SecurityUserWebLoginEntity>>();
|
||||
|
||||
SecurityUserWebLoginEntity webLogin = new SecurityUserWebLoginEntity
|
||||
{
|
||||
Username = securityUserEntity.UserName,
|
||||
SessionId = clainmName,
|
||||
LoginTime = DateTime.Now,
|
||||
HostIp = httpContextAccessor.HttpContext.Connection.RemoteIpAddress?.MapToIPv4()?.ToString(),
|
||||
HostUserAgent = this.httpContextAccessor?.HttpContext?.Request.Headers.UserAgent.ToString(),
|
||||
RefreshToken = jwtGenerate.GenerateRefreshToken(),
|
||||
RefreshTokenRefreshedTime = DateTime.Now,
|
||||
};
|
||||
|
||||
repositoryLog.InsertNow(webLogin);
|
||||
PermissionContext permissionContext = new PermissionContext(service);
|
||||
return new LoginProfile
|
||||
{
|
||||
Token = new JwtInfo() { AccessToken = accessToken, RefreshToken = webLogin.RefreshToken, CreatedTime = webLogin.RefreshTokenRefreshedTime },
|
||||
Username = securityUserEntity.UserName,
|
||||
UserType = securityUserEntity.UserType,
|
||||
UserLocalName = securityUserEntity.UserLocalName,
|
||||
UserEngName = securityUserEntity.UserEngName,
|
||||
UserMobile = securityUserEntity.UserMobile!,
|
||||
PermissionInfo = permissionContext.GetUserPermissionInfo()
|
||||
};
|
||||
}
|
||||
|
||||
[PermissionOperate(name: SecurityPermissionPolicy.SecurityUser, operate: "LoginAgent")]
|
||||
[UnitOfWork]
|
||||
public LoginProfile LoginAgent(LoginData data)
|
||||
{
|
||||
LoginProfile loginProfile = Login(data);
|
||||
|
||||
SecurityUserEntity agent = repository.DetachedEntities.Where(x =>
|
||||
(x.UserMobile == data.AgentUserName && x.UserIsValidIndc == YesNoPolicy.YES)).FirstOrDefault()!;
|
||||
|
||||
if (agent == null)
|
||||
{
|
||||
throw new ValidatedException("代理用户不存在.");
|
||||
}
|
||||
|
||||
JwtGenerate jwtGenerate = service.ServiceProvider.GetService<JwtGenerate>()!;
|
||||
|
||||
Dictionary<string, string> claims = new Dictionary<string, string>();
|
||||
claims.Add(ClaimPolicy.CLAINM_NAME, agent.UserName);
|
||||
claims.Add(ClaimPolicy.CLAINM_ACCOUNT, agent.UserMobile!);
|
||||
claims.Add(ClaimPolicy.CLAINM_USERID, agent.UserName);
|
||||
claims.Add(ClaimPolicy.CLAINM_LOCALE, data.Culture);
|
||||
|
||||
var accessToken = jwtGenerate.Generate(claims);
|
||||
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
httpContextAccessor.HttpContext.Request.Headers.Remove("Authorization");
|
||||
httpContextAccessor.HttpContext.Request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
|
||||
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey(ClaimPolicy.HEADER_LOCALE))
|
||||
httpContextAccessor.HttpContext.Request.Headers.Remove(ClaimPolicy.HEADER_LOCALE);
|
||||
httpContextAccessor.HttpContext.Request.Headers.Add(ClaimPolicy.HEADER_LOCALE, data.Culture);
|
||||
|
||||
SecurityUserWebLoginEntity webLogin = new SecurityUserWebLoginEntity
|
||||
{
|
||||
Username = agent.UserName,
|
||||
SessionId = Guid.NewGuid().ToString(),
|
||||
LoginTime = DateTime.Now,
|
||||
HostIp = loginProfile.Username,
|
||||
HostUserAgent = loginProfile.UserMobile!,
|
||||
RefreshToken = jwtGenerate.GenerateRefreshToken(),
|
||||
RefreshTokenRefreshedTime = DateTime.Now,
|
||||
};
|
||||
|
||||
IRepository<SecurityUserWebLoginEntity> repositoryLog = service.GetRepository<IRepository<SecurityUserWebLoginEntity>>();
|
||||
|
||||
repositoryLog.InsertNow(webLogin);
|
||||
|
||||
service.UserId = agent.UserName;
|
||||
PermissionContext permissionContext = new PermissionContext(service);
|
||||
return new LoginProfile
|
||||
{
|
||||
Token = new JwtInfo() { AccessToken = accessToken, RefreshToken = webLogin.RefreshToken, CreatedTime = webLogin.RefreshTokenRefreshedTime },
|
||||
Username = agent.UserName,
|
||||
UserType = agent.UserType,
|
||||
UserLocalName = agent.UserLocalName,
|
||||
UserEngName = agent.UserEngName,
|
||||
UserMobile = agent.UserMobile!,
|
||||
PermissionInfo = permissionContext.GetUserPermissionInfo()
|
||||
};
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[UnitOfWork]
|
||||
public string Register(RegisterData data)
|
||||
{
|
||||
SecurityUserEntity securityUser = repository.DetachedEntities.Where(x => x.UserMobile == data.UserMobile).FirstOrDefault()!;
|
||||
if (securityUser != null)
|
||||
{
|
||||
throw new ValidatedException("手机号已注册.");
|
||||
}
|
||||
|
||||
securityUser = new SecurityUserEntity();
|
||||
|
||||
if (string.IsNullOrEmpty(data.UserMobile) || string.IsNullOrEmpty(data.RsaUserPassword)) return null;
|
||||
|
||||
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
|
||||
string userName = securityGeneratorNumberService.GetNo(SecurityPrefixPolicy.SECURITY_USER, SecurityPrefixPolicy.SECURITY_USER_USER_NAME, null, YesNoPolicy.NO, SecurityPrefixPolicy.SECURITY_USER_FORMAT);
|
||||
|
||||
var privateKey = service.Configuration[SecuritySettingsPolicy.SecuritySettings_RsaPrivateKey];
|
||||
var rsa = new System.RSA(privateKey, true);
|
||||
|
||||
securityUser.UserPassword = rsa.DecodeOrNull(data.RsaUserPassword);
|
||||
//052636a8-b146-9efd-f5dc-0034a3c5bb34+password(MD5)
|
||||
string guid = securityUser.UserPassword.Substring(0, 36);
|
||||
|
||||
securityUser.UserPassword = securityUser.UserPassword.Substring(36, securityUser.UserPassword.Length - 36);
|
||||
securityUser.UserName = userName;
|
||||
securityUser.UserMobile = data.UserMobile;
|
||||
securityUser.UserLocalName = "用户" + securityUser.UserName;
|
||||
securityUser.UserIsValidIndc = YesNoPolicy.YES;
|
||||
|
||||
JwtGenerate jwtGenerate = service.ServiceProvider.GetService<JwtGenerate>()!;
|
||||
|
||||
Dictionary<string, string> claims = new Dictionary<string, string>();
|
||||
claims.Add(ClaimPolicy.CLAINM_NAME, securityUser.UserName);
|
||||
claims.Add(ClaimPolicy.CLAINM_ACCOUNT, securityUser.UserName);
|
||||
claims.Add(ClaimPolicy.CLAINM_USERID, securityUser.UserName);
|
||||
claims.Add(ClaimPolicy.CLAINM_LOCALE, CulturePolicy.ZH_CN);
|
||||
|
||||
service.UserId = securityUser.UserName;
|
||||
|
||||
var accessToken = jwtGenerate.Generate(claims);
|
||||
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
httpContextAccessor.HttpContext.Request.Headers.Remove("Authorization");
|
||||
httpContextAccessor.HttpContext.Request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
|
||||
repository.InsertNow(securityUser);
|
||||
|
||||
//发布注册的事务
|
||||
EventData eventData = new EventData();
|
||||
ISecurityUserRegisterPublisher publisher = service.ServiceProvider.GetService<ISecurityUserRegisterPublisher>()!;
|
||||
eventData.EventSource = securityUser;
|
||||
eventData.EventId = typeof(SecurityUserRegisterPublisher).Name;
|
||||
publisher.Publish(eventData);
|
||||
|
||||
return securityUser.UserMobile;
|
||||
}
|
||||
|
||||
[PermissionOperate(name: SecurityPermissionPolicy.SecurityUser, operate: Operate.Update)]
|
||||
[UnitOfWork]
|
||||
public LoginProfile AmendPassword(LoginData data)
|
||||
{
|
||||
SecurityUserEntity securityUserEntity = repository.DetachedEntities.Where(x =>
|
||||
x.UserName == service.UserId
|
||||
&& x.UserIsValidIndc == YesNoPolicy.YES).FirstOrDefault()!;
|
||||
|
||||
if (securityUserEntity == null)
|
||||
{
|
||||
throw new ValidatedException("认证不通过.");
|
||||
}
|
||||
|
||||
var descKey = service.Configuration[SecuritySettingsPolicy.SecuritySettings_DescKey];
|
||||
|
||||
var privateKey = service.Configuration[SecuritySettingsPolicy.SecuritySettings_RsaPrivateKey];
|
||||
var rsa = new RSA(privateKey, true);
|
||||
|
||||
var psd = rsa.DecodeOrNull(data.RsaUserPassword);
|
||||
if (string.IsNullOrEmpty(psd)) throw new ValidatedException("认证不通过.");
|
||||
//052636a8-b146-9efd-f5dc-0034a3c5bb34+password
|
||||
var guid = psd.Substring(0, 36);
|
||||
|
||||
|
||||
if (guid != data.UserName)
|
||||
{
|
||||
throw new ValidatedException("认证不通过.");
|
||||
}
|
||||
|
||||
if (securityUserEntity.IsAccountsLockedIndc == YesNoPolicy.YES && securityUserEntity.AccountsLockedDatetime.HasValue
|
||||
&& securityUserEntity.AccountsLockedDatetime.Value.Subtract(DateTime.Now).TotalMinutes > 0)
|
||||
{
|
||||
throw new ValidatedException("用户账号已锁定.");
|
||||
}
|
||||
|
||||
if (securityUserEntity.UserPassword != psd.Substring(36, psd.Length - 36))
|
||||
{
|
||||
securityUserEntity.ErrorLoginCount += 1;
|
||||
//输错多少次后,账号锁定
|
||||
if (securityUserEntity.ErrorLoginCount > SecurityUserPolicy.ERROR_LOGIN_COUNT)
|
||||
{
|
||||
securityUserEntity.IsAccountsLockedIndc = YesNoPolicy.YES;
|
||||
securityUserEntity.AccountsLockedDatetime = DateTime.Now.AddDays(1);
|
||||
}
|
||||
|
||||
repository.UpdateNow(securityUserEntity);
|
||||
|
||||
throw new ValidatedException("认证不通过.");
|
||||
}
|
||||
|
||||
JwtGenerate jwtGenerate = service.ServiceProvider.GetService<JwtGenerate>()!;
|
||||
|
||||
string clainmName = Guid.NewGuid().ToString();
|
||||
Dictionary<string, string> claims = new Dictionary<string, string>();
|
||||
claims.Add(ClaimPolicy.CLAINM_NAME, clainmName);
|
||||
claims.Add(ClaimPolicy.CLAINM_ACCOUNT, securityUserEntity.UserMobile!);
|
||||
claims.Add(ClaimPolicy.CLAINM_USERID, securityUserEntity.UserName);
|
||||
claims.Add(ClaimPolicy.CLAINM_LOCALE, data.Culture ?? CulturePolicy.ZH_CN);
|
||||
|
||||
var accessToken = jwtGenerate.Generate(claims);
|
||||
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
httpContextAccessor.HttpContext.Request.Headers.Remove("Authorization");
|
||||
httpContextAccessor.HttpContext.Request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
|
||||
securityUserEntity.ErrorLoginCount = 0;
|
||||
securityUserEntity.IsAccountsLockedIndc = YesNoPolicy.NO;
|
||||
securityUserEntity.AccountsLockedDatetime = null;
|
||||
//更新最后登录日期
|
||||
securityUserEntity.LastLoginDatetime = DateTime.Now;
|
||||
psd = rsa.DecodeOrNull(data.UserPassword);
|
||||
if (string.IsNullOrEmpty(psd)) throw new ValidatedException("认证不通过.");
|
||||
securityUserEntity.UserPassword = psd.Substring(36, psd.Length - 36);
|
||||
repository.UpdateNow(securityUserEntity);
|
||||
|
||||
IRepository<SecurityUserWebLoginEntity> repositoryLog = service.GetRepository<IRepository<SecurityUserWebLoginEntity>>();
|
||||
|
||||
SecurityUserWebLoginEntity webLogin = new SecurityUserWebLoginEntity
|
||||
{
|
||||
Username = securityUserEntity.UserName,
|
||||
SessionId = clainmName,
|
||||
LoginTime = DateTime.Now,
|
||||
HostIp = httpContextAccessor.HttpContext.Connection.RemoteIpAddress?.MapToIPv4()?.ToString(),
|
||||
HostUserAgent = this.httpContextAccessor?.HttpContext?.Request.Headers.UserAgent.ToString(),
|
||||
RefreshToken = jwtGenerate.GenerateRefreshToken(),
|
||||
RefreshTokenRefreshedTime = DateTime.Now,
|
||||
};
|
||||
|
||||
repositoryLog.InsertNow(webLogin);
|
||||
PermissionContext permissionContext = new PermissionContext(service);
|
||||
return new LoginProfile
|
||||
{
|
||||
Token = new JwtInfo() { AccessToken = accessToken, RefreshToken = webLogin.RefreshToken, CreatedTime = webLogin.RefreshTokenRefreshedTime },
|
||||
Username = securityUserEntity.UserName,
|
||||
UserType = securityUserEntity.UserType,
|
||||
UserLocalName = securityUserEntity.UserLocalName,
|
||||
UserEngName = securityUserEntity.UserEngName,
|
||||
UserMobile = securityUserEntity.UserMobile!,
|
||||
PermissionInfo = permissionContext.GetUserPermissionInfo()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet]
|
||||
public string GetRsaPublicKey()
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.Configuration["SecuritySettings:RsaPublicKey"]))
|
||||
throw new ValidatedException("[SecuritySettings:RsaPublicKey]");
|
||||
return service.Configuration["SecuritySettings:RsaPublicKey"]!;
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
public JwtInfo RefreshToken(JwtInfo jwtInfo)
|
||||
{
|
||||
if (jwtInfo == null || string.IsNullOrEmpty(jwtInfo.AccessToken) || string.IsNullOrEmpty(jwtInfo.RefreshToken))
|
||||
throw new ServiceErrorException("无效的令牌,请重新登录.");
|
||||
|
||||
TokenValidationParameters parameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuerSigningKey = true,
|
||||
//获取或设置要使用的Microsoft.IdentityModel.Tokens.SecurityKey用于签名验证。
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(service.CloudBuilder.CloudBuilderOptions.Jwt.Secret)),
|
||||
//获取或设置一个System.String,它表示将使用的有效发行者检查代币的发行者。
|
||||
ValidIssuer = service.CloudBuilder.CloudBuilderOptions.Jwt.Issuer,
|
||||
//获取或设置一个字符串,该字符串表示将用于检查的有效受众反对令牌的观众。
|
||||
ValidAudience = service.CloudBuilder.CloudBuilderOptions.Jwt.Audience,
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = false,//不验证过期时间
|
||||
};
|
||||
|
||||
// 验证 Token
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
SecurityToken vTocken;
|
||||
string token = jwtInfo.AccessToken.Replace("Bearer ", "");
|
||||
try
|
||||
{
|
||||
var tokenValidationResult = tokenHandler.ValidateToken(token, parameters, out vTocken);
|
||||
|
||||
if (tokenValidationResult == null || !tokenValidationResult.Identities.Any() || !tokenValidationResult.Identities.First().IsAuthenticated)
|
||||
throw new ServiceErrorException("无效的令牌,请重新登录.");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ServiceErrorException("无效的令牌,请重新登录.");
|
||||
}
|
||||
|
||||
string clainmName = ClaimPolicy.GetClaimValue(token, ClaimPolicy.CLAINM_NAME);
|
||||
string username = ClaimPolicy.GetClaimValue(token, ClaimPolicy.CLAINM_USERID);
|
||||
string userMobile = ClaimPolicy.GetClaimValue(token, ClaimPolicy.CLAINM_ACCOUNT);
|
||||
string locale = ClaimPolicy.GetClaimValue(token, ClaimPolicy.CLAINM_LOCALE);
|
||||
if (string.IsNullOrEmpty(clainmName) || string.IsNullOrEmpty(username))
|
||||
throw new ServiceErrorException("无效的令牌,请重新登录.");
|
||||
|
||||
IRepository<SecurityUserEntity> repositorySecurityUser = service.GetRepository<IRepository<SecurityUserEntity>>();
|
||||
|
||||
SecurityUserEntity user = repositorySecurityUser.DetachedEntities.Where(x => x.UserName == username && x.UserIsValidIndc == YesNoPolicy.YES).FirstOrDefault();
|
||||
if (user == null) throw new ServiceErrorException("无效的令牌,请重新登录.");
|
||||
|
||||
IRepository<SecurityUserWebLoginEntity> repositoryLog = service.GetRepository<IRepository<SecurityUserWebLoginEntity>>();
|
||||
|
||||
SecurityUserWebLoginEntity log = repositoryLog.DetachedEntities.Where(x => x.Username == username && x.SessionId == clainmName).FirstOrDefault()!;
|
||||
|
||||
//不是最后登录的令牌失效
|
||||
DateTime? LoginTime = repositoryLog.DetachedEntities.Where(x => x.Username == username).Max(x => x.LoginTime);
|
||||
if (LoginTime.HasValue && log.LoginTime < LoginTime.Value) throw new ServiceErrorException("无效的令牌,请重新登录.");
|
||||
|
||||
if (log == null || log.RefreshToken != jwtInfo.RefreshToken || log.LogoutTime.HasValue ||
|
||||
log.RefreshToken != jwtInfo.RefreshToken || log.RefreshTokenRefreshedTime.AddMinutes(Convert.ToInt32(service.CloudBuilder.CloudBuilderOptions.Jwt.RefreshExpireMins)) < DateTime.Now)
|
||||
throw new ServiceErrorException("无效的令牌,请重新登录.");
|
||||
|
||||
JwtGenerate jwtGenerate = service.ServiceProvider.GetService<JwtGenerate>()!;
|
||||
|
||||
Dictionary<string, string> claims = new Dictionary<string, string>();
|
||||
claims.Add(ClaimPolicy.CLAINM_NAME, clainmName);
|
||||
claims.Add(ClaimPolicy.CLAINM_ACCOUNT, userMobile);
|
||||
claims.Add(ClaimPolicy.CLAINM_USERID, username);
|
||||
claims.Add(ClaimPolicy.CLAINM_LOCALE, locale??CulturePolicy.ZH_CN);
|
||||
|
||||
var accessToken = jwtGenerate.Generate(claims);
|
||||
|
||||
log.RefreshToken = jwtGenerate.GenerateRefreshToken();
|
||||
log.RefreshTokenRefreshedTime = DateTime.Now;
|
||||
|
||||
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
httpContextAccessor.HttpContext.Request.Headers.Remove("Authorization");
|
||||
httpContextAccessor.HttpContext.Request.Headers.Add("Authorization", "Bearer " + accessToken);
|
||||
|
||||
repositoryLog.UpdateNow(log);
|
||||
|
||||
jwtInfo.AccessToken = accessToken;
|
||||
jwtInfo.RefreshToken = log.RefreshToken;
|
||||
jwtInfo.CreatedTime = log.RefreshTokenRefreshedTime;
|
||||
|
||||
return jwtInfo;
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
public void Logout()
|
||||
{
|
||||
string username = ClaimPolicy.GetClaimValue(httpContextAccessor, ClaimPolicy.CLAINM_USERID);
|
||||
string clainmName = ClaimPolicy.GetClaimValue(httpContextAccessor, ClaimPolicy.CLAINM_NAME);
|
||||
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(clainmName)) { return; }
|
||||
|
||||
|
||||
IRepository<SecurityUserWebLoginEntity> repositoryLog = service.GetRepository<IRepository<SecurityUserWebLoginEntity>>();
|
||||
|
||||
SecurityUserWebLoginEntity log = repositoryLog.DetachedEntities.Where(x => x.Username == username && x.SessionId == clainmName).FirstOrDefault()!;
|
||||
if (log == null || log.LogoutTime.HasValue) { return; }
|
||||
|
||||
log.LogoutTime = DateTime.Now;
|
||||
|
||||
repositoryLog.UpdateNow(log);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user