0

詳細な背景については、 http: //grails.markmail.org/message/62w2xpbgneapmhpdを参照してください。

BootStrap.groovy で Shiro SecurityUtils.getSubject() メソッドをモックアウトしようとしています。このアプローチを決定したのは、Shiro の最新バージョンの Subject ビルダーが現在のバージョンの Nimble プラグイン (私が使用している) では利用できないためです。SecurityUtils.metaClass を試してみることにしましたが、metaClasses の仕組みについて非常に基本的なことが欠けているように感じます。参考までに、私の 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 から件名を出力すると、"Canned Subject" が表示されます。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.

メタクラスがどのように機能するかについて不可欠な何かが欠けていますか?

4

1 に答える 1

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
}

いくつかのデバッグ ステートメントを追加したところ、表示されていたエラーが init クロージャの最後に発生していることがわかりました。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 から削除できるはずです。:-)

于 2009-11-12T19:06:37.873 に答える