2012-02-14 51 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