我面临一个概念问题:如何过滤对 Hibernate 加载的实体的某些属性的访问?
例如:我有一辆汽车,里面有 4 个轮子(2 个红色,2 个蓝色;双向链接);用户 A 有权看到红色和蓝色的轮子,用户 B 只能看到蓝色的轮子。当我检索 Cars 时,也会获取车轮(有时通过 Hibernate.initialize,有时通过直接在查询中获取)。
当我请求 Cars 时,我想找到一种方法将车轮过滤到仅用户有权查看的车轮。(DB加载后的过滤结果暂时可以)
我想保持过滤机制不那么具有侵入性。
什么不起作用:
@Filter(或@Where):凭据检查有点棘手,我还有其他一些连接要做,以了解是否允许用户查看轮子;
Spring ACL:我的凭证管理太棘手,无法使用(此外,不确定它是否能够过滤内部属性);
实施的解决方案:
- 定义一个自定义 UserCollectionType,并提供一个 Collection Decorator 仅检索授权数据(重载 iterator()、get(int index)、...);缺点:我的集合不连贯:添加数据时,只有在允许当前用户的情况下才能访问它。不确定这是一个可靠的解决方案。
其他解决方案:
域对象上的 AOP:我认为这是最好的;在我的域对象上添加 AOP,它定义了它的可授权实体集合的访问器,并在访问时过滤它们。不方便:在 hibernate 加载的域对象上添加 AOP 可能很棘手?(参见Spring AOP Advice for Hibernate managed POJO)
Hibernate Interceptor/Event:我尝试使用它,但没有找到做我想做的事的好地方,而不会被打扰。而且我不想“真正”修改加载的集合:它必须对休眠透明(我不希望休眠在每次用户 B 在非只读事务中访问它们时从汽车上移除红色轮子)。
AOP + Introspection on暴露服务:在事务上下文之外,递归过滤每个实体的每个集合属性以去除未经授权的元素;也许是更简单、侵入性更小的解决方案;缺点:集合属性不能保持不变;
您如何看待已实施的解决方案?关于如何做到这一点的任何其他想法?
(上下文是:Hibernate 4.1.3、Spring 3.1.1、java 7)
谢谢 !