我有一个Grails(2.3.6)应用程序,要求用户在访问应用程序之前登录。一旦他们成功登录,他们就会被重定向到一个在右上角显示其用户名的登录页面。我通过以下3段代码很好地工作(或者我认为):
// myapp/grails-app/realms/myapp/MyAppRealm.groovy:
class MyAppRealm {
def onSuccessfulLogin(Principal principal) {
// Lots of code
// If I logged in successfully with a username of "user1", then principal.name will be "user1" here.
UserHolder.name = principal.name
// Lots more code
}
}
在上面的代码中,如果身份验证层确定他们已成功登录,则会执行onSuccessfulLogin()
方法。 principal.name
值是他们登录的经过身份验证的用户名。如您所见,我将此值存储在UserHolder
POGO中,如下所示:
class UserHolder {
static String name = null
static String getName() {
name
}
static void setName(String n) {
name = n
}
}
然后,在我的GSP文件中:
// myapp/grails-app/views/page.gsp
You are logged in as ${UserHolder?.name}.
我刚刚向我报告说,测试人员成功登录,几分钟后,他们点击了F5并刷新了他们的屏幕,却发现他们的用户名属于另一个测试人员!查看代码后,原因很明显:UserHolder.name
是一个静态变量;在任何给定的时间点,它只有1个实例存在于服务器上。因此,如果user1
登录,他们会在用户界面中看到user1
作为用户名。但是,如果user2
然后登录,User.name
现在等于user2
,如果user1
刷新他们的屏幕,他们会看到user2
作为他们的用户名。
所以我的下一个想法是尝试将principal.name
存储在像session.name = principal.name
这样的会话变量中:
// myapp/grails-app/realms/myapp/MyAppRealm.groovy:
class MyAppRealm {
def onSuccessfulLogin(Principal principal) {
// Lots of code
// If I logged in successfully with a username of "user1", then principal.name will be "user1" here.
session.name = principal.name
// Lots more code
}
}
...然后在GSP中引用它You are logged in as ${session.name}.
。问题在于我无法从session
内部访问MyAppRealm.groovy
,而且不容易注射(除非有人能想到如何)。所以我问:我怎样才能记录" principal.name
结束MyAppRealm
,然后在GSP内指定正确的用户名?
答案 0 :(得分:1)
我的Groovy和Grails应用程序中有类似的要求。对您的解决方案并不是真正直接的答案,但您可以尝试类似的东西。这就是我所做的:
class UserController {
def register() {
if(request.method == 'POST') {
def u = new User()
u.properties[
'login',
'password',
'firstName',
'lastName',
] = params
if(u.save()) {
session.user = u
session.setMaxInactiveInterval(-1)
redirect(controller: "myController", action: "welcome")
}
}
在我看来,我用它如下:
Welcome ${session?.user?.firstName}
我的用户域类如下:
class User {
String login
String password
String firstName
String lastName
}
希望有所帮助:)
答案 1 :(得分:0)
我认为最简单的是使用TagLib。这是documentation
下面,您将找到一个使用Spring Security Core的小例子:
class ProfileTagLib {
def springSecurityService
static namespace = "prf"
static defaultEncodeAs = 'none'
def username = { attrs, body ->
def loggedInUser = springSecurityService.currentUser
if(loggedInUser) {
loggedInUser.attach()
out << loggedInUser.firstName
}
}
在我的gsp上,下一个标签是我唯一需要显示firstName:
<prf:username />
希望这有帮助
答案 2 :(得分:0)
上面已经发布了答案,但您可以在您的领域内访问会话。在这种情况下,您无法访问文件中某个位置的会话。
// Import this package.
import org.springframework.web.context.request.RequestContextHolder
// And then get the current session
def session = RequestContextHolder.currentRequestAttributes().getSession()