Использование groovy metaClass для имитации Shiro SecurityUtils в начальной загрузке

Дополнительную информацию см. На странице http://grails.markmail.org/message/62w2xpbgneapmhpd.

Я пытаюсь высмеять метод Shiro SecurityUtils.getSubject () в моем BootStrap.groovy. Я выбрал этот подход, потому что построитель предметов в последней версии Shiro недоступен в текущей версии плагина Nimble (который я использую). Я решил попробовать поиграть с SecurityUtils.metaClass, но чувствую, что мне не хватает чего-то очень важного в том, как работают метаклассы. Для справки, вот мой класс Trackable:

    abstract class Trackable {
       User createdBy
       Date dateCreated
       User lastUpdatedBy
       Date lastUpdated

       static constraints = {
           lastUpdated(nullable:true)
           lastUpdatedBy(nullable:true)
           createdBy(nullable:true)
       }

       def beforeInsert = {
           def subject

           try {
               subject = SecurityUtils.subject
           } catch (Exception e) {
               log.error "Error obtaining the subject.  Message is [${e.message}]"
           }

           createdBy = (subject ? User.get( subject.principal ) :
User.findByUsername("admin"))
       }

       def beforeUpdate = {
           def subject

           try {
               subject = SecurityUtils.subject
           } catch (Exception e) {
               log.error "Error obtaining the subject.  Message is [${e.message}]"
           }

           lastUpdatedBy = (subject ? User.get( subject.principal ) :
User.findByUsername("admin"))
       }
   }

В моем BootStrap.groovy у меня есть это:

   def suMetaClass = new ExpandoMetaClass(SecurityUtils)

   suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}

   suMetaClass.initialize()

   SecurityUtils.metaClass = suMetaClass

И это работает ... вроде как. Если я распечатаю тему из BootStrap.groovy, я получу «Консервированная тема». Если я попытаюсь создать и сохранить экземпляры подклассов Trackable, я получу:

No SecurityManager accessible to this method, either bound to
the org.apache.shiro.util.ThreadContext or as a vm static
singleton.  See the org.apache.shiro.SecurityUtils.getSubject()
method JavaDoc for an explanation of expected environment
configuration.

Мне не хватает чего-то неотъемлемого о том, как работают метаклассы?


person Matt Lachman    schedule 10.11.2009    source источник
comment
Интересно, может ли это быть связано с тем, что Grails 1.1.1 находится на Groovy 1.6.3? jira.codehaus.org/browse/GROOVY-3873   -  person Matt Lachman    schedule 12.11.2009


Ответы (1)


Я понял, что происходит. В моем BootStrap я делал что-то вроде этого:

def init = { servletContext->
  switch (Environment.current.name) {
    case "local":
      def suMetaClass = new ExpandoMetaClass(SecurityUtils)
      suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
      suMetaClass.initialize()
      SecurityUtils.metaClass = suMetaClass

      new TrackableSubClass().save()

      //Create some other domain instances

      SecurityUtils.metaClass = null
  }
  //Create a couple domain instances that aren't environment specific
}

Я добавил несколько операторов отладки и увидел, что ошибки, которые я видел, происходили в конце закрытия инициализации. Я немного погуглил, чтобы дважды проверить, как очистить сеанс Hibernate. Затем я внес следующие изменения:

def sessionFactory

def init = { servletContext->
  switch (Environment.current.name) {
    case "local":
      def suMetaClass = new ExpandoMetaClass(SecurityUtils)
      suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
      suMetaClass.initialize()
      SecurityUtils.metaClass = suMetaClass

      new TrackableSubClass().save()

      //Create some other domain instances

      sessionFactory.currentSession.flush()

      SecurityUtils.metaClass = null
  }
  //Create a couple domain instances that aren't environment specific
}

Кажется, проблема полностью решена, и теперь я могу удалить громоздкие блоки try / catch из Trackable. :-)

person Matt Lachman    schedule 12.11.2009