2017-05-08 56 views
1

我是使用Spring Security插件的新人,用於我的grails應用程序。這是我的代碼獲取當前用戶登錄。grails - 全局獲取當前用戶

String username = getPrincipal().username 

但事情是我在每一個行動寫這行以獲得當前用戶。有沒有辦法在全球範圍內獲得當前用戶?並在一次又一次的動作中使用它,而不是一次又一次地宣告它?

+0

創建一個名爲BaseController的類,並讓每個控制器擴展它,然後在其中創建一個受保護的方法,可以從所有控制器訪問。 – Raphael

回答

2

你可以做到這一點在2種方式:
1)你可以注入SpringSecurityService任何你想要的,只需在任何控制器/服務:

SpringSecurityService springSecurityService 

def someMethod(){ 
    springSecurityService.principal 
} 

2)可以使用SecurityContextHolder中:

def someMethod(){ 
    SecurityContextHolder.context.authentication?.principal 
} 

我建議使用選項1,它使測試更容易等。

0

如果您需要獲取用戶對象,我建議您檢索「新鮮」使用用戶實例每次(從數據庫獲取)springSecurityService之前注入:

springSecurityService.principal.username 

但是如果你只需要一個用戶名 - 你可以創建一個會話範圍的bean,並在用戶名來填充它創建時間:

resources.groovy

... 
userNameHolder(UserNameHolder) { bean -> 
    bean.scope = 'session' 
    springSecurityService = ref("springSecurityService") 
} 
... 

和:

class UserNameHolder { 
    def springSecurityService 

    String username = springSecurityService.principal.username 

    String getUsername() { 
     username 
    } 
} 

那麼你應該注入UserNameHolder到所需要的地方,找回用戶名:

class SomeService { 

    def userNameHolder 

    void someMethod() { 
     ... 
     userNameHolder.username 
     ... 
    } 
    ... 
} 

享受!

UPD

你可以做通過將用戶名到HttpSession中幾乎是相同的,但它會更可控和可測試性。所以我強烈建議你使用會話範圍的bean。

+0

'springSecurityService.currentUser?.userName'除非'userName'屬性在委託人上不可用,否則會執行不必​​要的數據庫調用。 'springSecurityService.principal.username'會更好。 –

+0

@JamesKleeh,謝謝,考慮到了;) –