代码之家  ›  专栏  ›  技术社区  ›  Matt Lachman

使用groovy元类模拟引导中的shiro securityUtils

  •  0
  • Matt Lachman  · 技术社区  · 15 年前

    有关更多背景信息,请参见 http://grails.markmail.org/message/62w2xpbgneapmhpd

    我正在尝试模仿bootstrap.groovy中的shiro securityUtils.getSubject()方法。我决定采用这种方法,因为最新Shiro版本的SubjectBuilder在当前版本的灵活插件(我正在使用)中不可用。我决定尝试使用securityUtils.metaclass,但我觉得我缺少一些关于元类如何工作的非常基本的东西。以下是我的可跟踪类,供参考:

        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”。如果我尝试创建和保存可跟踪子类的实例,我会得到:

    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.
    

    关于元类是如何工作的,我是否遗漏了一些不可分割的东西?

    1 回复  |  直到 9 年前
        1
  •  1
  •   Matt Lachman    15 年前

    我知道发生了什么事。在我的引导下,我做了这样的事情:

    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结束时。我在google上搜索了一下如何刷新我的冬眠会话。然后我做了以下更改:

    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
    }
    

    这似乎已经完全解决了这个问题,现在我应该能够从trackable中删除繁琐的try/catch块。-)