在Spring Security事件监听器中保留Groovy模型

时间:2012-02-14 14:18:52

标签: grails spring-security gorm

我已经在config.groovy中添加了一个onAuthenticationSuccessEvent,以便尝试将Login模型添加到用户User模型中的列表中。我遇到的问题是,事件监听器是一个闭包,因此没有HibernateSession或访问闭包之外的状态。

我知道可以通过这样做来绑定HibernateSession:

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

问题是Login属于User,需要在其构造函数中定义User。如何将用户传递到闭包中?

我想做类似的事情:

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

但不知道如何传递特定用户。

2 个答案:

答案 0 :(得分:1)

您不能执行Login.withTransaction{ user ->,因为传递给withTransaction方法的闭包参数采用的是TransactionStatus参数 - 您无法指定类型,只是名字。

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

您希望在User块中加载withTransaction,因为它与事务处于相同的Hibernate会话中,否则Login保存将失败,因为{{1}将被断开连接。并且使用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

答案 1 :(得分: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)
}