Использование Groovy MetaClass для издевания Shiro SecurityUtils в начальной загрузке
-
19-09-2019 - |
Вопрос
Для дальнейшего фона см. http://grails.markmail.org/message/62w2xpbgneapmhpd
Я пытаюсь издеваться над методом Shiro SecurityUtils.getSubject () в моем Bootstrap.grovy. Я определился с этим подходом, потому что субъект -строитель в последней версии Shiro не доступен в текущей версии плагина Limble (который я использую). Я решил попробовать поиграть с SecurityUtils.MetaClass, но у меня есть ощущение, что у меня не хватает чего -то очень фундаментального в отношении того, как работают 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"))
}
}
В моем начале.
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
И это работает ... вроде. Если я распечатаю тему из Bootstrap.groovy, я получаю «консервированный предмет». Если я попытаюсь создать и сохранить экземпляры подклассов отслеживаемых, я получаю:
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.
Я упускаю что -то неотъемлемое в том, как работают MetaClasses?
Решение
Я выяснил, что происходит. В моем начальной загрузке я делал что -то вроде этого:
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
}
Я добавил некоторые заявления отладки и увидел, что ошибки, которые я видел, происходили в конце закрытия инициации. Я сделал несколько гуглей, чтобы дважды проверить, как промыть сеанс Whibernate. Затем я сделал следующие изменения:
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
}
Похоже, что это полностью решило проблему, и теперь я смогу удалить громоздкие блоки Try/поймать от Trackable. :-)