.NET WebApi清洁架构下基于身份的查询过滤方案选型
清洁架构下基于AD组过滤数据的方案选择
方案分析与建议
1. 将辅助类改为服务,应用层定义接口、上层实现
这是最符合清洁架构原则的方案。
- 核心思路:在应用层定义
IUserGroupChecker接口,把IsUserInGroup方法纳入接口;WebApi层(接口适配器层)实现该接口,封装AD查询的具体逻辑。 - 优势:
- 遵循依赖倒置原则:应用层依赖抽象而非具体实现,完全与AD这类外部服务解耦,便于单元测试(可Mock接口实现)。
- 业务逻辑内聚:应用层的用例(如
GetValuation)可以直接调用接口完成组检查,自行构建数据过滤条件,确保业务规则(权限+数据过滤)的完整性。
- 代码示例:
应用层接口:
WebApi层实现:public interface IUserGroupChecker { bool IsUserInGroup(string userName, string userGroup); }
应用层使用:public class AdUserGroupChecker : IUserGroupChecker { public bool IsUserInGroup(string userName, string userGroup) { // 原静态类的AD查询逻辑 return isUserInGroup; } }private readonly IUserGroupChecker _userGroupChecker; public ValuationService(IUserGroupChecker userGroupChecker) { _userGroupChecker = userGroupChecker; } public List<MyObjectDto> GetValuation(int valuationId, string userName) { bool isInAdminGroup = _userGroupChecker.IsUserInGroup(userName, "AdminGroup"); // 根据组信息构建filterExpression var filterExpression = isInAdminGroup ? x => x.Id == valuationId : x => x.Id == valuationId && x.IsPublic; var myObjectList = _repository.Get(filterExpression, includesProperties); return myObjectList; }
2. 控制器检查组后传入结果
- 弊端:
- 授权逻辑分散到控制器层,应用层的业务逻辑依赖外部传入的权限结果,导致业务规则不内聚。如果后续有其他入口(如后台服务、控制台程序)调用应用层方法,需要手动传递权限信息,容易遗漏或出错。
- 应用层无法自主掌控权限规则,违背了清洁架构中“应用层封装业务用例”的核心思想。
- 仅适合非常简单的场景,不推荐用于中大型项目。
3. 将辅助类移至应用层
完全不可行。清洁架构要求应用层独立于外部框架和服务(AD属于外部依赖),将AD查询逻辑移入应用层会导致:
- 应用层与AD强耦合,无法在不依赖AD的环境下测试。
- 破坏分层边界,违背“内层不依赖外层”的原则。
其他优化建议
- 封装
UserContext:在WebApi层通过中间件从请求头获取用户名、所属组等信息,封装为UserContext对象,通过依赖注入传递给应用层。应用层依赖IUserContext接口,无需每次手动传递用户名,代码更简洁:public interface IUserContext { string UserName { get; } bool IsInGroup(string groupName); } - 结合策略模式:如果不同组的过滤逻辑差异较大,可以将过滤逻辑封装为策略类,应用层根据用户组选择对应策略,进一步解耦业务逻辑与权限规则。
内容的提问来源于stack exchange,提问作者Dumitru Laurenţiu
相关产品推荐
相关产品推荐

