2012-02-14 38 views
0

我已经将onAuthenticationSuccessEvent添加到了我的config.groovy中,以便尝试将登录模型添加到用户用户模型中的列表中。我遇到的问题是,事件监听器是一个闭包,因此没有HibernateSession或访问状态以外的闭包。Spring安全事件监听器中持久化的Groovy模型

我知道它可以通过做这样的事情的HibernateSession绑定:

grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx -> 
    Login.withTransaction{ 
     login = new Login() 
    } 
} 

的问题是,登录属于用户,并且需要在其构造函数中定义的用户。我如何将用户传递给关闭?

我想要做的事,如:

def user = grails.admin.User.read(appCtx.springSecurityService.currentUser.id) 
Login.withTransaction{ user -> 
    login = new Login(user: user) 
} 

,但不知道如何通过特定的用户在

回答

1

你不能这样做,因为Login.withTransaction{ user ->你传递给withTransaction方法关闭的参数需要一个参数,它是TransactionStatus - 你没有得到指定类型,只是名字。

但我不确定为什么你会看到你所看到的关闭范围。关闭关闭很酷的事情是,他们包围他们的范围,因此名称。所以闭包之外的变量总是可用的。

你会希望UserwithTransaction块里面装虽然所以它是在同一个Hibernate Session作为交易的,否则Login保存会失败,因为User将被断开。并且使用load()而不是read(),因为您只需在Login中设置外键,因此load()的效果最好,因为它只创建代理并且不会触及数据库,但会使id可用于Login保存。出于同样的原因,您希望避免使用currentUser方法,因为它只是User.get()的快捷方式。

说了这么多,这为我工作:

grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx -> 
    Login.withTransaction { status -> 
     new Login(user: appCtx.springSecurityService.currentUser).save() 
    } 
} 

但是由于e变量是InteractiveAuthenticationSuccessEvent你最好不要使用这样的:

grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx -> 
    Login.withTransaction { status -> 
     def user = User.load(e.authentication.principal.id) 
     new Login(user: user).save() 
    } 
} 
0

你为什么不能做一些事情像下面,就取里面的用户。关闭。

Login.withNewSession { 
    def user = grails.admin.User.read(appCtx.springSecurityService.currentUser.id) 
    login = new Login(user: user) 
} 

OR

Login.withTransaction{ 
    def user = grails.admin.User.read(appCtx.springSecurityService.currentUser.id) 
    login = new Login(user: user) 
} 
+0

我不能这样做,因为该同样的原因,我不能在闭包中引用用户 - 闭包不包含事件处理程序其余部分的范围,因此appCtx对象在闭包中也为null。我最终得到“无法获得属性'currentUser'null对象。”所以我需要将用户或appCtx作为属性关闭,但不知道如何。 – 2012-02-14 17:17:24