Преглед на файлове

fix: 修复域登录问题,并拆分域登录与租户域名登录配置

喵你个旺呀 преди 1 година
родител
ревизия
1ced9487ee

+ 5 - 0
Admin.NET/Admin.NET.Core/Const/ConfigConst.cs

@@ -70,6 +70,11 @@ public class ConfigConst
     /// 域登录验证
     /// </summary>
     public const string SysDomainLogin = "sys_domain_login";
+    
+    /// <summary>
+    /// 租户域名隔离登录验证
+    /// </summary>
+    public const string SysTenantHostLogin = "sys_tenant_host_login";
 
     /// <summary>
     /// 数据校验日志

+ 1 - 0
Admin.NET/Admin.NET.Core/SeedData/SysConfigSeedData.cs

@@ -31,6 +31,7 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
             new SysConfig{ Id=1300000000191, Name="RefreshToken过期时间", Code=ConfigConst.SysRefreshTokenExpire, Value="20160", SysFlag=YesNoEnum.Y, Remark="刷新Token过期时间(分钟)(一般 refresh_token 的有效时间 > 2 * access_token 的有效时间)", OrderNo=100, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
             new SysConfig{ Id=1300000000201, Name="发送异常日志邮件", Code=ConfigConst.SysErrorMail, Value="False", SysFlag=YesNoEnum.Y, Remark="是否发送异常日志邮件", OrderNo=110, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
             new SysConfig{ Id=1300000000211, Name="域登录验证", Code=ConfigConst.SysDomainLogin, Value="False", SysFlag=YesNoEnum.Y, Remark="是否开启域登录验证", OrderNo=120, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
+            new SysConfig{ Id=1300000000212, Name="租户隔离登录验证", Code=ConfigConst.SysTenantHostLogin, Value="False", SysFlag=YesNoEnum.Y, Remark="租户隔离登录验证", OrderNo=370, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
             new SysConfig{ Id=1300000000221, Name="数据校验日志", Code=ConfigConst.SysValidationLog, Value="True", SysFlag=YesNoEnum.Y, Remark="是否数据校验日志", OrderNo=130, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
             new SysConfig{ Id=1300000000231, Name="行政区域同步层级", Code=ConfigConst.SysRegionSyncLevel, Value="3", SysFlag=YesNoEnum.Y, Remark="行政区域同步层级 1-省级,2-市级,3-区县级,4-街道级,5-村级", OrderNo=140, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
             new SysConfig{ Id=1300000000301, Name="系统主标题", Code=ConfigConst.SysWebTitle, Value="Admin.NET", SysFlag=YesNoEnum.Y, Remark="系统主标题", OrderNo=300, GroupCode=ConfigConst.SysWebConfigGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },

+ 52 - 37
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs

@@ -64,30 +64,17 @@ public class SysAuthService : IDynamicApiController, ITransient
         if (passwordMaxErrorTimes < 1) passwordMaxErrorTimes = 10;
         if (passwordErrorTimes > passwordMaxErrorTimes) throw Oops.Oh(ErrorCodeEnum.D1027);
 
-        // 是否开启验证码
-        if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysCaptcha))
-        {
-            // 判断验证码
-            if (!_captcha.Validate(input.CodeId.ToString(), input.Code)) throw Oops.Oh(ErrorCodeEnum.D0008);
-        }
-        // 是否开启域登录验证
-        var isDomainLogin = await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysDomainLogin);
-
-        // 获取租户
-        var tenant = await GetTenantByHost(input.Host, isDomainLogin);
-
-        // 账号是否存在
-        var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter().FirstAsync(u => (u.TenantId == tenant.Id || u.AccountType == AccountTypeEnum.SuperAdmin) && u.Account.Equals(input.Account));
-        _ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
+        // 判断是否开启验证码,其校验验证码
+        if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysCaptcha) && !_captcha.Validate(input.CodeId.ToString(), input.Code)) throw Oops.Oh(ErrorCodeEnum.D0008);
         
-        // 若登录的是超级管理员,则引用当前绑定的租户,这样登陆后操作的租户数据才会与该租户关联
-        if (user.AccountType == AccountTypeEnum.SuperAdmin) user.TenantId = tenant.Id;
+        // 获取登录租户和用户
+        var (tenant, user) = await GetLoginUserAndTenant(input.Host, account: input.Account);
 
         // 账号是否被冻结
         if (user.Status == StatusEnum.Disable) throw Oops.Oh(ErrorCodeEnum.D1017);
 
         // 是否开启域登录验证
-        if (isDomainLogin)
+        if (await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysDomainLogin))
         {
             var userLdap = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysUserLdap>>().GetFirstAsync(u => u.UserId == user.Id && u.TenantId == tenant.Id);
             if (userLdap == null)
@@ -110,22 +97,57 @@ public class SysAuthService : IDynamicApiController, ITransient
     }
     
     /// <summary>
-    /// 根据绑定域名获取租户
+    /// 获取登录户和用
     /// </summary>
     /// <param name="host"></param>
-    /// <param name="isDomainLogin"></param>
+    /// <param name="account"></param>
+    /// <param name="phone"></param>
     /// <returns></returns>
-    private async Task<SysTenant> GetTenantByHost(string host, bool isDomainLogin)
+    [NonAction]
+    public async Task<(SysTenant tenant, SysUser user)> GetLoginUserAndTenant(string host, string account=null, string phone=null)
     {
-        if (!isDomainLogin) return await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().GetFirstAsync(u => u.Id == SqlSugarConst.DefaultTenantId);
-        // 若租户域名为空或为本地域名,则取默认租户域名
-        if (string.IsNullOrWhiteSpace(host) || host.StartsWith("localhost")) host = SqlSugarConst.DefaultTenantHost;
+        // 是否租户隔离登录验证
+        var isTenantHostLogin = await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysTenantHostLogin);
         
-        // 租户是否存在或已禁用
-        var tenant = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().GetFirstAsync(u => u.Host == host.ToLower());
-        if (tenant?.Status != StatusEnum.Enable) throw Oops.Oh(ErrorCodeEnum.Z1003);
+        SysUser user;
+        SysTenant tenant;
+        
+        // 租户隔离登录
+        if (isTenantHostLogin)
+        {
+            // 若租户域名为空或为本地域名,则取默认租户域名
+            if (string.IsNullOrWhiteSpace(host) || host.StartsWith("localhost")) host = SqlSugarConst.DefaultTenantHost;
+            
+            // 租户是否存在或已禁用
+            tenant = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().GetFirstAsync(u => u.Host == host.ToLower());
+            if (tenant?.Status != StatusEnum.Enable) throw Oops.Oh(ErrorCodeEnum.Z1003);
+
+            // 根据入参类型、租户查询登录用户
+            user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter()
+                .Where(u => u.TenantId == tenant.Id || u.AccountType == AccountTypeEnum.SuperAdmin)
+                .WhereIF(!string.IsNullOrWhiteSpace(account), u => u.Account.Equals(account))
+                .WhereIF(!string.IsNullOrWhiteSpace(phone), u => u.Account.Equals(phone))
+                .FirstAsync();
+            _ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
+        }
+        else
+        {
+            // 根据入参类型查询登录用户
+            user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter()
+                .WhereIF(!string.IsNullOrWhiteSpace(account), u => u.Account.Equals(account))
+                .WhereIF(!string.IsNullOrWhiteSpace(phone), u => u.Account.Equals(phone))
+                .FirstAsync();
+            _ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
+            
+            // 租户是否存在或已禁用
+            tenant = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().GetFirstAsync(u => u.Id == user.TenantId);
+            if (tenant?.Status != StatusEnum.Enable) throw Oops.Oh(ErrorCodeEnum.Z1003);
+        }
+        
+        // 若登录的是超级管理员,则引用当前绑定的租户,这样登陆后操作的租户数据才会与该租户关联
+        if (user.AccountType == AccountTypeEnum.SuperAdmin) user.TenantId = tenant.Id;
 
-        return tenant;
+        return (tenant, user);
     }
 
     /// <summary>
@@ -200,15 +222,8 @@ public class SysAuthService : IDynamicApiController, ITransient
         // 校验短信验证码
         App.GetRequiredService<SysSmsService>().VerifyCode(new SmsVerifyCodeInput { Phone = input.Phone, Code = input.Code });
         
-        // 是否开启域登录验证
-        var isDomainLogin = await _sysConfigService.GetConfigValue<bool>(ConfigConst.SysDomainLogin);
-
-        // 获取租户
-        var tenant = await GetTenantByHost(input.Host, isDomainLogin);
-        
-        // 账号是否存在
-        var user = await _sysUserRep.AsQueryable().Includes(u => u.SysOrg).ClearFilter().FirstAsync(u => (u.TenantId == tenant.Id || u.AccountType == AccountTypeEnum.SuperAdmin) && u.Phone.Equals(input.Phone));
-        _ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
+        // 获取登录租户和用户
+        var (_, user) = await GetLoginUserAndTenant(input.Host, phone: input.Phone);
 
         return await CreateToken(user);
     }