2010-02-11 3 views
2

Я хотел бы перехватить вызовы на свойства классов домена для реализации контроля доступа.Перехват собственности классов домена Grails

Моя первая попытка была переопределить setProperty и getProperty. Делая это, я отключил все приятные функциональные возможности классов домена Grails, таких как

domainClass.properties = params 

и автоматическое преобразование типов данных.

Следующая попытка состояла в том, чтобы использовать DelegatingMetaClass, что позволило мне хотя бы распечатать несколько приятных сообщений журнала вокруг фактического вызова. Но я не мог понять, как получить доступ к фактическому объекту для оценки разрешений.

Последнее, groovy.lang.Interceptor, кажется, хороший выбор, так как я могу получить доступ к фактическому объекту. Но правильно ли это? Как я могу заставить все классы домена перехватываться?

Большое спасибо.

С уважением, Daniel

ответ

4

Вы можете переопределить GetProperty и SetProperty до тех пор, как вы ссылки на реальные версии. Добавьте код, как это Bootstrap для добавлений перехватчики для всех доменных классов:

class BootStrap { 

    def grailsApplication 

    def init = { servletContext -> 

     for (dc in grailsApplication.domainClasses) { 
     dc.class.metaClass.getProperty = { String name -> 
      // do stuff before access 
      def result 
      def metaProperty = delegate.class.metaClass.getMetaProperty(name) 
      if (metaProperty) { 
       result = metaProperty.getProperty(delegate) 
      } 
      else { 
       throw new MissingPropertyException(name, delegate.class) 
      } 
      // do stuff after access 
      result 
     } 

     dc.class.metaClass.setProperty = { String name, value -> 
      // do stuff before update 
      def metaProperty = delegate.class.metaClass.getMetaProperty(name) 
      if (metaProperty) { 
       metaProperty.setProperty(delegate, value) 
      } 
      else { 
       throw new MissingPropertyException(name, delegate.class) 
      } 
      // do stuff after update 
     } 
     } 
    } 

    def destroy = {} 
} 
+0

Здравствуйте, Спасибо большое за быстрый ответ. Ваш код очень помогает мне. К сожалению, я не вижу, как вызвать метод на моем объекте класса домена. Например, у меня есть класс домена под названием A, который предоставляет метод, называемый isReadable (String propertyName). Итак, как я могу вызвать эту функцию в методе get или setProperty? Я могу найти мета-метод через delegate.metaClass.getMetaMethod («isReadable», java.lang.String), но вызов всегда приводит к исключению (java.lang.IllegalArgumentException: object не является экземпляром класса объявления). С уважением, Daniel – Daniel

+0

Один из подходов заключается в замене комментария «do stuff before access» вызовом некоторого вспомогательного класса и проверки доступа. Что-то вроде «PropertyChecker.isReadable (delegate.class, name)», где PropertyChecker.isReadable (Class clazz, String name) делает что-то вроде «if (clazz == Person && name ==« username ») {...}". Этот помощник также может получить доступ к зарегистрированному пользователю для более мелкомасштабных проверок доступа. Это было бы ужасно быстро, поэтому вы захотите придумать какой-нибудь компактный способ представить, что людям разрешено изменять, читать и когда. –

+0

Спасибо за ваш ответ. Но я не понимаю, почему я не могу получить доступ к методам внутри класса. Я думал, что, определяя метод setProperty, этот метод фактически заменяется так, как если бы он был написан в самом классе домена. Пример вашего PropertyChecker предполагает, что я не могу работать с реальным объектом, а скорее с классом. К сожалению, этого недостаточно для меня, поскольку сам объект вычисляет права в зависимости от его состояния. Есть ли другие возможности, как перехватить набор и получить вызовы свойств? С уважением, Даниэль – Daniel

Смежные вопросы