在引导程序中使用 groovy 元类模拟 Shiro SecurityUtils
Posted
技术标签:
【中文标题】在引导程序中使用 groovy 元类模拟 Shiro SecurityUtils【英文标题】:Using groovy metaClass to mock out Shiro SecurityUtils in bootstrap 【发布时间】:2010-12-15 00:52:21 【问题描述】:更多背景信息,请参阅http://grails.markmail.org/message/62w2xpbgneapmhpd
我试图在我的 BootStrap.groovy 中模拟 Shiro SecurityUtils.getSubject() 方法。我决定采用这种方法是因为最新 Shiro 版本中的主题构建器在当前版本的 Nimble 插件(我正在使用)中不可用。我决定尝试使用 SecurityUtils.metaClass 但我觉得我错过了关于元类如何工作的一些非常基本的东西。作为参考,这是我的 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"))
在我的 BootStrap.groovy 中,我有这个:
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = [getPrincipal:2, toString:"Canned Subject"] as Subject
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
这行得通……有点。如果我从 BootStrap.groovy 打印出主题,我会得到“罐头主题”。如果我尝试创建和保存 Trackable 子类的实例,我会得到:
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.
我是否遗漏了有关元类如何工作的一些重要内容?
【问题讨论】:
我想知道这是否相关,因为 Grails 1.1.1 在 Groovy 1.6.3 上? jira.codehaus.org/browse/GROOVY-3873 【参考方案1】:我知道发生了什么。在我的 BootStrap 中,我正在做这样的事情:
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
我添加了一些调试语句,发现我看到的错误发生在 init 闭包的末尾。我做了一些谷歌搜索来仔细检查如何刷新我的 Hibernate 会话。然后我做了以下更改:
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
这似乎完全解决了问题,现在我应该能够从 Trackable 中删除繁琐的 try/catch 块。 :-)
【讨论】:
以上是关于在引导程序中使用 groovy 元类模拟 Shiro SecurityUtils的主要内容,如果未能解决你的问题,请参考以下文章