【问题标题】:Defining access-level based on object's field value根据对象的字段值定义访问级别
【发布时间】:2012-08-02 03:30:11
【问题描述】:
假设这个类(在 groovy 中):
class Class_A {
String type
...
}
我想根据类型的值定义对其实例的访问级别。例如,如果类型值为“T1”,则某些用户将对 Class_A 具有读取访问权限,而如果类型值为“T2”,则其他用户对其具有读取访问权限。
请不要提供基于继承的解决方案。我可以使用 spring-security 或 apache shiro 吗?
【问题讨论】:
标签:
java
grails
spring-security
shiro
【解决方案1】:
据我所知,没有开箱即用的插件可以解决这个问题,但我已经使用 shiro 实现了限制对对象的访问的项目。
你的问题将分成两个独立的问题:
a) 限制对对象的直接访问 - 没有权限的用户不应该能够访问这些对象的显示页面
b) 过滤列表和搜索 - 没有正确权限的用户不应在概览列表和搜索结果中看到这些对象
我对 a) 的解决方案:
创建一个过滤器类 (http://grails.org/doc/latest/guide/single.html#filters) 并为每个控制器添加一个before-filter,它能够显示要用于的对象得到保障。在此过滤器中,您可以预取对象并检查权限。如果它们不匹配,您可以重定向到拒绝访问页面。 (当您在控制器中第二次请求对象时,Hibernate 似乎足够聪明,可以从缓存中获取对象)
顺便说一句:这样,您还可以实现其他隐式权限和角色(例如,仅当用户自己创建对象时才显示对象)
我对 b) 的解决方案:
在大多数项目中,您必须修改列表视图并添加搜索。那么为什么不简单地添加一个搜索条件作为对象的过滤器呢?如果您使用标准构建器,添加额外的标准很容易......但您必须确保以正确的方式完成分页和排序。
希望对您有所帮助。
【解决方案2】:
Apache Shiro 可以做到这一点,但确实需要一些工作。
在我的解决方案中,我实现了一个经典的 RBAC 模型并提供了一个覆盖这些方法的自定义 AuthorizingRealm
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal)
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
返回的 AuthorizationInfo 应该包含用户应该拥有的角色和权限。
SimpleAuthorizationInfo authInfo= new SimpleAuthorizationInfo( acl.getRoles() );
authInfo.addStringPermissions( acl.getPermissions() );
return authInfo;
在 Shiro 中权限定义为:
domain:action:instance
因此,在您的示例中,此字符串权限将允许对 Class_A 的 T1 实例进行编辑
Class_A:edit:T1
您还可以允许“所有”操作或实例。
Class_A:*:T1 // allow all actions
or
Class_A:edit:* // allow edit of all instances
希望这会有所帮助。