grails中基于角色的域类字段访问

时间:2010-02-14 14:51:57

标签: grails acl grails-plugin

我正在开发一个grails应用程序。在某些情况下我想根据角色控制域类字段。所以在每次调用域类的getter setter方法时我想根据角色应用一些过滤器(Logged)在用户的角色中。我假设grails将在运行时为domin类创建getter setter方法。所以在编写grails代码时可以应用这个逻辑。如果有可能那么如何应用?

示例:

域类:

class Book{
   String name;
   double price;

  }

控制器:

def index={
  Book book=Book.get(1);
   println book.name;
   println book.price;
 }

在上面的代码中“println book.price;”这一行应仅适用于特定角色。对于某些其他角色,它应该抛出一些异常。

是否可以实现?有没有插件可以做到这一点?

请对此提供一些帮助....谢谢

2 个答案:

答案 0 :(得分:1)

您可以为要控制访问的属性创建get / set方法,并将安全逻辑放在那里。假设您已编写自己的安全服务或正在使用安全插件,如Spring Security(Acegi)插件,您将:

class Book{
    String name;
    double price;

    def authenticateService

    void setPrice(double price) {
        if(!authenticateService.ifAllGranted('ROLE_PRICE_FIXER')) {
            throw new Exception("You are not authorized to set book prices")
        }
        this.price = price
    }

    double getPrice() {
        if(!authenticateService.ifAllGranted('ROLE_PRICE_FIXER')) {
            throw new Exception("You are not authorized to get book prices")
        }
        return this.price
    }
}

我不知道任何允许将访问控制放在域属性上的插件。

答案 1 :(得分:0)

您还可以考虑使用自定义验证程序或弹出错误对象来捕获在保存之前设置字段的尝试。

编辑:以下是我在想的一个例子。你可以概括一点,这里的代码还没有经过测试,所以它可能不会按原样运行。

class securedDomain {
    String securedField

    def fieldSetBy = [:]
    def previousValue = [:]
    static transients = ['fieldSetBy', 'previousValue']

    static constraints = {
        securedField(validator: { v, o ->
             def access = User.findByName(fieldSetBy['securedField']).hasAccess('securedField')
             if(!access) securedField = previousValue['securedField']
             return access
        })

    void setProperty(String name, value) {
        if(name == "securedField") {
            fieldSetBy['securedField'] = session.user
            previousValue['securedField'] = securedField
            securedField = value
        } else {
            super(name, value)
        }
    }