Verwenden von Groovy Metaclass, um Shiro Securityutils in Bootstrap zu verspotten
-
19-09-2019 - |
Frage
Für weitere Hintergrund http://grails.markmail.org/message/62W2XPBGNEAPMHPD
Ich versuche, die Shiro SecurityUtils.GetSubject () -Methode in meiner Bootstrap.groovy zu verspotten. Ich habe mich für diesen Ansatz entschieden, weil der Betreff der neuesten Shiro -Version in der aktuellen Version des Nimble -Plugins (das ich verwende) nicht verfügbar ist. Ich habe mich entschlossen, mit den Securityutils zu spielen. Als Referenz hier ist meine verfolgbare Klasse:
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"))
}
}
In meinem Bootstrap.Groovy habe ich Folgendes:
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
Und das funktioniert ... irgendwie. Wenn ich das Thema von Bootstrap ausdruckenin ausdrucken habe, bekomme ich "Dosenmotiv". Wenn ich versuche, Instanzen von Unterklassen von Trackable zu erstellen und zu speichern, bekomme ich:
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.
Vermisse ich etwas Integrales darüber, wie Metaklasse funktioniert?
Lösung
Ich fand heraus, was geschah. In meiner Bootstrap machte ich so etwas:
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
}
Ich fügte einige Debug -Aussagen hinzu und sah, dass die Fehler, die ich sah, am Ende des Init -Verschlusses auftraten. Ich habe etwas gegoogelt, um zu überprüfen, wie ich meine Hibernate -Sitzung spülen kann. Dann habe ich die folgenden Änderungen vorgenommen:
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
}
Das scheint das Problem vollständig gelöst zu haben, und jetzt sollte ich in der Lage sein, die umständlichen Versuchs-/Fangblöcke von Trackable zu entfernen. :-)