在Grails中使用Hibernate Filter为Domain的所有GORM动态查询添加通用的数据过滤条件
? ? ? 如果在作一个系统时,希望某个用户登录只能查看到属于他自己创建的数据,而这个数据可能是来自很多个不同的实体/表,如电话营销代表登录系统后只能看见属于自己的或自己创建的客户,销售员登录系统后只能看见是自己客户的销售订单...,也就是说我们可能希望在几十个实体类/表,或者在一个超类的所有子类应用中使用一组固定的数据过滤条件,那么这就是Hibernate Filter要做的事情。应用它,你可以以一种非常轻松且安全的方式来实现此类需求。
? ? ? 在Grails中,我们同样希望在一个或多个Domain的所有动态finder中实现此需求,如findAllByUserName, finderAllByCustomer等等动态的GORM方法调用得么的集合中以自动透明的方式过滤掉一些不在权限范围内的数据,利用Hibernate Filter的Grails插件也可以以Groovy的方式来使用Hibernate Filter了。
? ? ? 如果在Grails项目中使用了Spring Security Core 的 Grails插件,那么如何与此集成,在Filter中传入用户的一些关键认证信息呢?请参考:
?
class MyDomain { Customer customer def springSecurityService static hibernateFilters = { def user = User.load(springSecurityService.principal.id) enabledFilter(condition:"customer_id=${user.company.id}", default:true) }}
?
请注意:你必须在condition中使用实际数据库表的字段名称,而不是 Domain 的 field 名称,比如在这段代码中,是“customer_id”而不是customer,否则运行将导致失败。
?
? ? ? 另外一个值得注意的是,在如下代码中
?
class Employee { String name static hasMany = [myCustomers:Partner] static constraints = { } static hibernateFilters = { enabledPartnersFilter(collection:'myCustomers', default:true) //注释1 }}class Partner { String name boolean enabled static constraints = { } static hibernateFilters = { enabledFilter(condition:'enabled=1', default:true) }}
?1. 采用注释1处的代码块,程序无法启动,目前还没找到解决办法,有高手知道的,请指点。
?2. 如果取消注释1处的代码,调用employee.myCustomers()后,不会过滤其中enabled属性为false 的 partner 集合项。 ? ? 目前还没有时间去研究其解决办法
?
在整个对Hibernate filter Plugin的论证过程中,发现它用于复杂的权限及数据过滤,可能会显得有些力不从心,毕竟Hibernate filter的本质无非是在SQL语句中的where部分自动添加一些额外的查询参数而已,对于大型或者复杂的方案,可能还是得自己通过Groovy式的AOP方式去寻求特定情况下的自定义方案,可以参见我的另一篇博客:在 Grails 中利用闭包实现查询条件的动态构造,利用 Groovy 的闭包和MOP元数据两大杀手锏,你几乎可以做到无所不能。
?
一些参考文档:
1.Hibernate Filter 参考手册:http://oss.org.cn/ossdocs/framework/hibernate/reference-v3_zh-cn/filters.html
2.Hibernate Filter Grails 插件:http://grails.org/plugin/hibernate-filter
3.来自Java Dzone的一篇示例文章:Introduction to Hibernate Filters
4.如何在Filter中定义多个参数的解决方法:http://wuhaixing.iteye.com/blog/305692#comments
5.一封来自Grails邮件列表的讨论:http://grails.1312388.n4.nabble.com/Extending-all-dynamic-finders-with-additional-query-parameters-td1391672.html
6.一封更长的来自Grails邮件讨论列表,提到了它的可用性和不可用性:http://grails.1312388.n4.nabble.com/Dynamic-Hibernate-Filters-tt3390194.html#a3390228
?
以上体会仅供参考。
?