ServiceStack AutoFilter失效:多租户数据访问控制问题排查
解决ServiceStack AutoFilter多租户数据过滤失效问题
问题根源排查
首先明确:AutoFilter仅自动应用于OrmLite的查询API(如Db.Select<T>()、Db.Single<T>()等),不会自动作用于Create/Update/Delete等写入操作。你的测试如果涉及写入操作,自然看不到过滤效果;如果是查询操作仍失效,按以下步骤排查:
确认查询方式正确
AutoFilter仅对ServiceStack OrmLite的标准查询方法生效,如果你用原生SQL、自定义SqlExpression且未手动调用过滤器,或者直接访问数据库,过滤规则不会自动应用。检查会话与UserSession定义
确保你的UserSession类包含ClientOrgId属性,且当前请求的会话已正确赋值:public class CustomUserSession : AuthUserSession { public Guid ClientOrgId { get; set; } }查询前可通过
SessionAs<CustomUserSession>()确认会话值是否正确。验证AutoFilter配置
你的模型配置本身语法没问题,但推荐用QueryTerm.And明确添加AND条件(效果和Ensure一致,但语义更清晰):[AutoFilter(QueryTerm.And, nameof(ClientOrgId), Eval = "userSession.ClientOrgId")] public class ClientObjectTableModel : AuditBase { // 现有字段... }检查OrmLite配置
确保未在配置中禁用AutoFilters(默认是启用的):var dbFactory = new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider); dbFactory.EnableAutoFilters = true; // 显式启用,确保生效
自定义查询时手动应用过滤器
如果使用自定义SqlExpression,需要手动调用ApplyAutoFilters来启用规则:
public object Get(QueryClientObjects request) { var q = Db.From<ClientObjectTableModel>() .Where(x => x.ClientName.Contains(request.SearchTerm)) .ApplyAutoFilters(Request); // 手动应用AutoFilter var results = Db.Select(q); return new QueryClientObjectsResponse { Results = results }; }
写入操作的租户验证
AutoFilter不处理写入,需手动验证传入数据的租户标识与会话一致:
public object Post(CreateClientObject request) { var session = SessionAs<CustomUserSession>(); if (request.ClientOrgId != session.ClientOrgId) throw new UnauthorizedAccessException("无权操作其他租户的数据"); var newObj = request.ConvertTo<ClientObjectTableModel>(); Db.Save(newObj); return new ClientObjectMutationResponse { Id = newObj.Id }; }
测试固定值过滤的正确姿势
测试固定值时,执行标准查询方法:
// 模型上临时添加固定值过滤 [AutoFilter(QueryTerm.And, nameof(ClientLocation), Value = "The Fourth Moon Of Mars")] public class ClientObjectTableModel : AuditBase { ... } // 执行查询,查看结果是否被过滤 var filteredData = Db.Select<ClientObjectTableModel>();
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

