En utilisant MetaClass groovy pour se moquer des Shiro SecurityUtils dans bootstrap
-
19-09-2019 - |
Question
Pour des informations plus, consultez http://grails.markmail.org/message/62w2xpbgneapmhpd
Je suis en train de se moquer de la méthode Shiro SecurityUtils.getSubject () dans mon BootStrap.groovy. J'ai décidé cette approche parce que le constructeur Sujet dans la dernière version Shiro n'est pas disponible dans la version actuelle du plugin Nimble (dont je me sers). Je décidé d'essayer de jouer avec le SecurityUtils.metaClass mais j'ai un sentiment que je me manque quelque chose de très fondamental sur la façon dont fonctionnent 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'imprimer le sujet de BootStrap.groovy je reçois « conserve Objet ». 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.
Suis-je manque quelque chose sur la façon intégrale Métaclasses travail?
La solution
Je me suis dit 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. Je l'ai fait quelques googler 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
}
Cela 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. : -)