2017-05-08 54 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,谢谢,考虑到了;) –