123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- using Furion.DatabaseAccessor.Extensions;
- using Furion.EventBus;
- using Microsoft.Extensions.Options;
- using UAParser;
- using YBEE.EQM.Core;
- namespace YBEE.EQM.Application;
- /// <summary>
- /// 认证服务
- /// </summary>
- public class SysAuthService(IOptions<AuthOptions> options,
- IHttpContextAccessor httpContextAccessor,
- IEventPublisher eventPublisher,
- IRepository<SysUser> userRep,
- ISysRoleUserService roleUserService,
- ISysMenuService menuService,
- IGeneralCaptchaService captchaService) : ISysAuthService, ITransient
- {
- private readonly AuthOptions _authOptions = options.Value;
- /// <summary>
- /// 登录处理
- /// </summary>
- /// <param name="accountLoginInput">账户密码</param>
- /// <returns></returns>
- private async Task<AuthOutput> Login(LoginInput accountLoginInput)
- {
- var checkCaptcha = captchaService.CheckCode(accountLoginInput.Captcha);
- if (checkCaptcha.Code != 0)
- {
- throw Oops.Oh(checkCaptcha.Message);
- }
- string pwd = "";
- string newPwd = "";
- try
- {
- pwd = RSAEncryption.Decrypt(accountLoginInput.Password, _authOptions.RsaPrivateKey);
- if (!string.IsNullOrEmpty(accountLoginInput.NewPassword))
- {
- newPwd = RSAEncryption.Decrypt(accountLoginInput.NewPassword, _authOptions.RsaPrivateKey);
- if (pwd == newPwd)
- {
- throw Oops.Oh(ErrorCode.E1009);
- }
- }
- }
- catch
- {
- throw Oops.Oh("密码格式错误!");
- }
- //// 判断用户名和密码是否正确 忽略全局过滤器
- //var users = await _userRep.DetachedEntities
- // .Include(t => t.SysOrg)
- // .Where(u => (u.Account.Equals(accountLoginInput.Account) || u.Mobile.Equals(accountLoginInput.Account) || u.Email.Equals(accountLoginInput.Account)) && u.IsDeleted == false)
- // .ToListAsync();
- var user = await userRep.Include(t => t.SysOrg)
- .FirstOrDefaultAsync(u => u.IsDeleted == false &&
- (u.Account.Equals(accountLoginInput.Account) ||
- u.Mobile.Equals(accountLoginInput.Account) ||
- u.Email.Equals(accountLoginInput.Account)
- )) ?? throw Oops.Oh(ErrorCode.E1001);
- //if (!AESEncryption.Decrypt(user.Password, _authOptions.AesPassword).Equals(pwd))
- if (!PBKDF2Encryption.Compare(pwd, user.Password))
- {
- throw Oops.Oh(ErrorCode.E1001);
- }
- //var user = (users?.FirstOrDefault(u => AESEncryption.Decrypt(u.Password, _authOptions.AesPassword).Equals(pwd))) ?? throw Oops.Oh(ErrorCode.E1001);
- if (!user.IsActivated && newPwd != "")
- {
- //user.Password = AESEncryption.Encrypt(newPwd, _authOptions.AesPassword);
- user.Password = PBKDF2Encryption.Encrypt(newPwd);
- user.IsActivated = true;
- user.ActivateTime = DateTime.Now;
- await user.UpdateIncludeNowAsync(new[] { nameof(user.Password), nameof(user.IsActivated), nameof(user.ActivateTime) });
- }
- AuthOutput ret = new()
- {
- OrgName = user.SysOrg.Name,
- Name = user.Name,
- Account = user.Account,
- IsActivated = user.IsActivated,
- AccessToken = "",
- };
- if (!user.IsActivated)
- {
- return ret;
- }
- // 验证账号是否被冻结
- if (user.Status == CommonStatus.DISABLE)
- {
- throw Oops.Oh(ErrorCode.E1003);
- }
- var isSuperAdmin = await roleUserService.IsSuperAdmin(user.Id);
- // 生成Token令牌
- var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
- {
- {ClaimConst.CLAINM_USERID, user.Id},
- {ClaimConst.CLAINM_ACCOUNT, user.Account},
- {ClaimConst.CLAINM_NAME, user.Name},
- {ClaimConst.CLAINM_ORGID, user.SysOrgId},
- {ClaimConst.CLAINM_ORGNAME, user.SysOrg.Name},
- {ClaimConst.CLAINM_SUPERADMIN, isSuperAdmin.ToString()},
- });
- // 设置Swagger自动登录
- httpContextAccessor.HttpContext.SigninToSwagger(accessToken);
- // 生成刷新Token令牌
- var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, App.GetOptions<RefreshTokenSettingOptions>().ExpiredTime);
- // 设置刷新Token令牌
- httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
- ret.AccessToken = accessToken;
- return ret;
- }
- /// <summary>
- /// 账户密码登录
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- public async Task<AuthOutput> LoginByAccount([Required] LoginInput input)
- {
- return await Login(accountLoginInput: input);
- }
- /// <summary>
- /// 获取当前登录用户信息
- /// </summary>
- /// <returns></returns>
- public async Task<LoginOutput> GetLoginUser()
- {
- var user = await userRep.Include(t => t.SysOrg).FirstOrDefaultAsync(u => u.Id == CurrentSysUserInfo.SysUserId) ?? throw Oops.Oh(ErrorCode.E1002);
- var userId = user.Id;
- var loginOutput = user.Adapt<LoginOutput>();
- var httpContext = httpContextAccessor.HttpContext;
- loginOutput.LastLoginTime = user.LastLoginTime = DateTime.Now;
- loginOutput.LastLoginIp = user.LastLoginIp = httpContext.GetRequestIPv4();
- var client = Parser.GetDefault().Parse(httpContext.Request.Headers["User-Agent"]);
- loginOutput.LastLoginBrowser = client.UA.Family + client.UA.Major;
- loginOutput.LastLoginOs = client.OS.Family + client.OS.Major;
- // 角色信息
- loginOutput.SysRoles = await roleUserService.GetLoginUserRoleList(userId);
- // 权限信息
- loginOutput.Permissions = await menuService.GetLoginPermissionList(userId);
- // 系统所有权限信息
- loginOutput.AllPermissions = await menuService.GetAllPermissionList();
- // 菜单信息
- loginOutput.Menus = await menuService.GetLoginAntMenus(userId);
- // 更新用户最后登录Ip和时间
- await userRep.UpdateIncludeAsync(user, new[] { nameof(SysUser.LastLoginIp), nameof(SysUser.LastLoginTime) });
- // 增加登录日志
- await eventPublisher.PublishAsync(new ChannelEventSource("Create:VisLog",
- new SysLogVis
- {
- Name = loginOutput.Name,
- Success = true,
- Message = "登录成功",
- Ip = loginOutput.LastLoginIp,
- Browser = loginOutput.LastLoginBrowser,
- Os = loginOutput.LastLoginOs,
- VisType = LoginType.LOGIN,
- VisTime = loginOutput.LastLoginTime,
- Account = loginOutput.Account
- }));
- return loginOutput;
- }
- /// <summary>
- /// 退出
- /// </summary>
- /// <returns></returns>
- public async Task Logout()
- {
- var ip = httpContextAccessor.HttpContext.GetRequestIPv4();
- httpContextAccessor.HttpContext.SignoutToSwagger();
- //_httpContextAccessor.HttpContext.Response.Headers["access-token"] = "invalid token";
- // 增加退出日志
- await eventPublisher.PublishAsync(new ChannelEventSource("Create:VisLog",
- new SysLogVis
- {
- Name = CurrentSysUserInfo.Name,
- Success = true,
- Message = "退出成功",
- VisType = LoginType.LOGOUT,
- VisTime = DateTime.Now,
- Account = CurrentSysUserInfo.Account,
- Ip = ip
- }));
- }
- /// <summary>
- /// 获取验证码
- /// </summary>
- /// <returns></returns>
- public Task<GeneralCaptchaOutput> GetCaptcha()
- {
- // 图片大小要与前端保持一致(坐标范围)
- return Task.FromResult(captchaService.CreateCaptchaImage());
- }
- /// <summary>
- /// 校验验证码
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- public Task<GeneralCaptchaOutput> VerifyCaptcha(GeneralCaptchaInput input)
- {
- return Task.FromResult(captchaService.CheckCode(input));
- }
- /// <summary>
- /// 获取临时密码
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- public List<string> GetTempPassword(List<string> input)
- {
- List<string> ret = [];
- foreach (string pwd in input)
- {
- //var npwd = AESEncryption.Encrypt(pwd, _authOptions.AesPassword);
- var npwd = PBKDF2Encryption.Encrypt(pwd);
- ret.Add(npwd);
- }
- return ret;
- }
- }
|