// using IP2Region.Net.Abstractions; namespace SafeCampus.System; /// /// 认证模块事件总线 /// public class AuthEventSubscriber : IEventSubscriber, ISingleton { private readonly ISimpleCacheService _simpleCacheService; private readonly ISearcher _searcher; public IServiceProvider Services { get; } private readonly SqlSugarScope _db; public AuthEventSubscriber(ISimpleCacheService simpleCacheService, IServiceProvider services, ISearcher searcher) { _db = DbContext.DB; _simpleCacheService = simpleCacheService; _searcher = searcher; Services = services; } /// /// 登录事件 /// /// /// [EventSubscribe(EventSubscriberConst.LOGIN_B)] public async Task Login(EventHandlerExecutingContext context) { var loginEvent = (LoginEvent)context.Source.Payload;//获取参数 var loginAddress = GetLoginAddress(loginEvent.Ip); var sysUser = loginEvent.SysUser; #region 登录/密码策略 var key = SystemConst.CACHE_LOGIN_ERROR_COUNT + sysUser.Account;//获取登录错误次数Key值 _simpleCacheService.Remove(key);//移除登录错误次数 // 创建新的作用域 using var scope = Services.CreateScope(); // 解析服务 var configService = scope.ServiceProvider.GetRequiredService(); var messageService = scope.ServiceProvider.GetRequiredService(); var pwdRemindUpdateTime = sysUser.PwdRemindUpdateTime;//获取上次提醒修改密码时间 var loginPolicy = await configService.GetConfigsByCategory(CateGoryConst.CONFIG_PWD_POLICY);//获取密码策略 //获取用户token列表 var tokenInfos = _simpleCacheService.HashGetOne>(CacheConst.CACHE_USER_TOKEN, sysUser.Id.ToString()); var userToken = tokenInfos.Where(it => it.Token == loginEvent.Token).FirstOrDefault(); if (userToken != null) { var subject = "请及时修改密码"; //如果上次修改密码时间为空 if (pwdRemindUpdateTime == null) { var pwdUpdateDefault = loginPolicy.First(x => x.ConfigKey == SysConfigConst.PWD_UPDATE_DEFAULT).ConfigValue.ToBoolean();//获取初始化提醒 //如果密码初始化提醒为true if (pwdUpdateDefault) { await messageService.Send(new MessageSendInput { Subject = subject, Content = "请及时修改初始密码", Category = CateGoryConst.MESSAGE_INFORM, ReceiverIdList = new List { sysUser.Id } }); } sysUser.PwdRemindUpdateTime = DateTime.Now;//设置提醒时密码时间为当前时间 } else { var pwdRemind = loginPolicy.First(x => x.ConfigKey == SysConfigConst.PWD_REMIND).ConfigValue.ToBoolean();//获取密码提醒天数 if (pwdRemind) { var pwdRemindDay = loginPolicy.First(x => x.ConfigKey == SysConfigConst.PWD_REMIND_DAY).ConfigValue.ToInt();//获取密码提醒时间 if (DateTime.Now - pwdRemindUpdateTime > TimeSpan.FromDays(pwdRemindDay)) { await messageService.Send(new MessageSendInput { Subject = subject, Content = $"已超过{pwdRemindDay}天未修改密码,请及时修改密码", Category = CateGoryConst.MESSAGE_INFORM, ReceiverIdList = new List { sysUser.Id } }); } sysUser.PwdRemindUpdateTime = DateTime.Now;//设置提醒时密码时间为当前时间,避免重复提醒 } } } #endregion 登录/密码策略 #region 重新赋值属性,设置本次登录信息为最新的信息 sysUser.LastLoginAddress = sysUser.LatestLoginAddress; sysUser.LastLoginDevice = sysUser.LatestLoginDevice; sysUser.LastLoginIp = sysUser.LatestLoginIp; sysUser.LastLoginTime = sysUser.LatestLoginTime; sysUser.LatestLoginAddress = loginAddress; sysUser.LatestLoginDevice = loginEvent.Device.ToString(); sysUser.LatestLoginIp = loginEvent.Ip; sysUser.LatestLoginTime = loginEvent.DateTime; #endregion 重新赋值属性,设置本次登录信息为最新的信息 //更新用户登录信息 if (await _db.UpdateableWithAttr(sysUser).UpdateColumns(it => new { it.LastLoginAddress, it.LastLoginDevice, it.LastLoginIp, it.LastLoginTime, it.LatestLoginAddress, it.LatestLoginDevice, it.LatestLoginIp, it.LatestLoginTime, LastUpdatePwdTime = it.PwdRemindUpdateTime }).ExecuteCommandAsync() > 0) _simpleCacheService.HashAdd(SystemConst.CACHE_SYS_USER, sysUser.Id.ToString(), sysUser);//更新Redis信息 await Task.CompletedTask; } /// /// 登出事件 /// /// /// [EventSubscribe(EventSubscriberConst.LOGIN_OUT_B)] public async Task LoginOut(EventHandlerExecutingContext context) { _ = (LoginEvent)context.Source.Payload;//获取参数 } /// /// 解析IP地址 /// /// ip地址 /// private string GetLoginAddress(string ip) { try { var ipInfo = _searcher.Search(ip).Replace("0|", "");//解析ip并格式化 return ipInfo; } catch { return "未知"; } } }