使用Groovy Metaclass在Bootstrap中嘲笑Shiro Securityutils
-
19-09-2019 - |
题
有关进一步的背景,请参阅 http://grails.markmail.org/message/62w2xpbgneapmhpd
我正在尝试在Bootstrap.groovy中嘲笑Shiro Security.getSubject()方法。我之所以决定这种方法,是因为最新版本中的主题构建器在当前版本的Nimble插件(我正在使用)中没有。我决定尝试使用SecurityUtils.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"))
}
}
在我的bootstrap.groovy中,我有:
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.
我是否缺少关于元类的工作不可或缺的东西?
解决方案
我弄清楚发生了什么。在我的引导程序中,我正在做这样的事情:
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
}
我添加了一些调试陈述,发现我看到的错误是在闭合结束时发生的。我进行了一些谷歌搜索,以仔细检查如何冲洗冬眠的课程。然后我进行了以下更改:
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
}
这似乎已经完全解决了这个问题,现在我应该能够从可跟踪的可删除笨拙的尝试/捕获块。 :-)
不隶属于 StackOverflow