2009-11-10 16 views
0

Pour des informations plus, voir http://grails.markmail.org/message/62w2xpbgneapmhpdEn utilisant MetaClass groovy pour se moquer des Shiro SecurityUtils dans bootstrap

Je suis en train de se moquer de la méthode Shiro SecurityUtils.getSubject() dans mon BootStrap.groovy. J'ai décidé de cette approche parce que le constructeur Sujet dans la dernière version de Shiro n'est pas disponible dans la version actuelle du plugin Nimble (que j'utilise). J'ai décidé d'essayer de jouer avec SecurityUtils.metaClass mais j'ai le sentiment qu'il me manque quelque chose de très fondamental sur le fonctionnement des métaClasses. Pour référence, voici ma classe 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")) 
     } 
    } 

Dans mon BootStrap.groovy, j'ai ceci:

def suMetaClass = new ExpandoMetaClass(SecurityUtils) 

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

    suMetaClass.initialize() 

    SecurityUtils.metaClass = suMetaClass 

Et ça fonctionne ... en quelque sorte. Si j'imprime le sujet de BootStrap.groovy je reçois "Sujet en conserve". Si je tente de créer et d'enregistrer des cas de sous-classes de courrier international, je reçois:

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. 

Est-ce que je manque quelque chose sur la façon intégrale Métaclasses travail?

+0

Je me demande si cela pourrait être lié puisque Grails 1.1.1 est sur Groovy 1.6.3? http://jira.codehaus.org/browse/GROOVY-3873 –

Répondre

1

J'ai compris ce qui se passait. Dans mon BootStrap je faisais quelque chose comme ceci:

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 
} 

J'ai ajouté quelques instructions de débogage et vu que les erreurs que je voyais se passait à la fin de la fermeture init. J'ai fait un peu de googling pour vérifier comment vider ma session Hibernate. Ensuite, je fait les modifications suivantes:

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 
} 

qui semble avoir complètement résolu le problème et maintenant je devrais être en mesure d'éliminer les blocs try/catch encombrants de traçable. :-)