问题描述:当用户角色数据范围为DataScopeEnum.Self时,GetByIdAsync查询返回null,而DataScopeEnum.All时有返回值。这是因为SqlSugarFilter中的数据权限过滤机制在起作用:
在SetDataScopeFilter方法中,当检测到用户数据范围为Self时,会为实体添加过滤器,只允许查询当前用户创建的数据(CreateUserId=当前用户ID)。
如果SysUser表的记录没有正确设置CreateUserId字段,或者查询时没有绕过过滤器,就会导致查询不到结果。
解决方案
方案1:临时禁用过滤器(推荐)
修改GetBaseInfo方法,临时禁用数据权限过滤:
[DisplayName("查看用户基本信息")]
public virtual async Task<SysUser> GetBaseInfo()
{
// 使用WithCache和DisableAllFilters来绕过过滤器
var model = await _sysUserRep.AsQueryable().DisableAllFilters().InSingleAsync(_userManager.UserId);
var msg = $"Test msg GetBaseInfo UserId:{_userManager.UserId} model:{(model == null ? string.Empty : JsonConvert.SerializeObject(model))}";
return model == null ? throw Oops.Oh(ErrorCodeEnum.D1002) : model;
}
方案2:确保SysUser实体不受数据权限过滤影响
修改SqlSugarFilter,将SysUser实体排除在数据权限过滤之外:
private static int SetDataScopeFilter(SqlSugarScopeProvider db)
{
// ... 其他代码不变
foreach (var entityType in entityTypes)
{
// 排除SysUser实体不受数据权限过滤影响
if (entityType == typeof(SysUser))
continue;
// ... 原有过滤逻辑
}
// ... 其他代码不变
}
方案3:确保SysUser记录有正确的CreateUserId
检查数据库中的SysUser表,确保每条记录都有正确的CreateUserId值。对于系统初始用户或管理员用户,可能需要手动设置。
最佳实践建议
用户基本信息查询应该绕过数据权限:像GetBaseInfo这样的方法查询的是用户自己的信息,应该不受数据权限限制。
区分不同类型的查询:
个人信息查询:不应用数据权限
用户管理查询:应用数据权限
考虑添加特性标记:可以创建一个[BypassDataPermission]特性来标记那些应该绕过权限检查的方法。
日志记录:在数据权限过滤器中添加详细的日志记录,帮助调试类似问题。
通过上述任一方案,应该能解决当用户角色为DataScopeEnum.Self时查询不到用户信息的问题。方案1是最直接的解决方案,因为它只在特定方法中禁用过滤器,不会影响系统的整体权限控制逻辑。