Usando MetaClass maravilloso para burlarse cabo Shiro SecurityUtils de arranque
-
19-09-2019 - |
Pregunta
Para más antecedentes, véase http://grails.markmail.org/message/62w2xpbgneapmhpd
Estoy tratando de burlar a cabo el método () en mi BootStrap.groovy Shiro SecurityUtils.getSubject. Me decidí por este enfoque porque el constructor Asunto en la última versión Shiro no está disponible en la versión actual del plugin ágil (que estoy usando). Decidí probar a jugar con el SecurityUtils.metaClass pero tengo la sensación de que me falta algo fundamental acerca de cómo funcionan metaclases. Como referencia, aquí está mi clase rastreable:
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"))
}
}
En mi BootStrap.groovy, tengo esto:
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
Y eso funciona ... más o menos. Si imprimo el tema desde BootStrap.groovy consigo "Canned Asunto". Si trato de crear y guardar instancias de subclases de rastreable, me sale:
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.
Me estoy perdiendo algo integral sobre cómo funcionan las metaclases?
Solución
Me di cuenta de lo que estaba ocurriendo. En mi BootStrap que estaba haciendo algo como esto:
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
}
He añadido algunas sentencias de depuración y vi que los errores que estaba viendo estaban sucediendo en el extremo del cierre init. Hice un poco de googling que vuelva a comprobar cómo vaciar mi sesión de Hibernate. Entonces hice los siguientes cambios:
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
}
Eso parece haber resuelto completamente el problema y ahora debería ser capaz de eliminar los bloques try / catch engorrosos desde rastreable. : -)