3

我正在使用 Acegi/Spring Security 插件在 Grails 中编写一个 Web 应用程序,并且无法让它查看我对用户实例所做的更改。我只使用 Groovy/Grails 大约三周,所以如果这个问题是微不足道的,请原谅我,因为我一直在研究邮件列表和教程试图找到答案。

每当我需要用户包含更多信息(例如电子邮件确认令牌或真实姓名)时,我一直在向用户域类添加新属性,因为我找不到任何相反的建议。创建新用户似乎一切都很好,但是当我编辑用户时,更改显示在用户列表中,但 Acegi 标记库和相关函数似乎没有看到更改。

这是来自 UserController.update() 的相关片段:

def person = User.get(params.id)
//...snip error checking...

//Update user attributes
person.username = params.email
person.email = params.email
person.userRealName = params.userRealName

//Attempt to save changes
if (person.save()) {
    //If successful, redirect back to profile viewing page
    redirect action: show, id: person.id
    return
}
else {
    //Otherwise, show errors and edit again
    render view: 'edit', model: buildPersonModel(person)
    return
}

这段代码运行后,如果我总是按 ID 获取用户数据,我可以看到更改,但如果我使用 Acegi 标记或函数则看不到。例如,这不起作用:

loggedInUserInfo(field:'realName')

但这确实:

User.get(loggedInUserInfo(field:'id').toLong()).realName

新信息有时会在我注销并再次登录后出现,但通常不会出现,即使在 3 次或更多重新登录后通常也不会出现。另外,我尝试在 person.save() 中添加“flush:true”,但没有任何效果。

(外围问题:像这样摆弄 User 类对我来说是不是很糟糕?如果不是,向其中添加信息的最佳方法是什么?)

更多调查后更新: 看起来如果我在普通页面中使用 loggedInUserInfo(),它工作正常,但如果我在布局中使用它,它会表现出我描述的行为。会不会发生一些奇怪的缓存事情?

4

6 回答 6

2

我有一个解决这个问题的方法,我还为这个问题创建了一个JIRA条目。

Acegi 如何在内部更新其用户似乎存在错误。我以 grails 过滤器的形式提供了一种解决方法,它在每次访问控制器时手动更新用户的权限。不理想,但它有效。

干杯,

于 2009-11-20T11:35:16.297 回答
2

您在修改用户类后是否运行了 grails generate-manager?

于 2009-05-30T18:27:50.853 回答
1

我面临着同样的问题。我的解决方案是将 acegi 插件更新到 0.5.1 版(acegi 0.5.1 -- Grails Spring Security 2.0 插件)。

然后我设置在/plugins/acegi-0.5.1/grails-app/conf/DefaultSecurityConfig.groovy

cacheUsers = false

现在瞧!这是工作!

路易斯

于 2010-01-19T15:44:04.713 回答
1

我遇到了同样的问题,并遵循了上面 Maximilian Schweitzer 的建议。一开始它对我不起作用。

试试这些步骤,看看它是否能解决问题:

  1. 我按照 Maximilian Schweitzer 的上述回答运行了 generate-manager 。
  2. 尝试使用在我运行 generate-manager 之前创建的用户登录 - 没有用
  3. 我创建了新用户(使用新的 UserController、gsp 等)
  4. 尝试使用新用户登录工作正常。
  5. 删除之前创建的旧用户并重新创建它们。它工作得很好。

虽然不确定它是否适用于您的情况。

于 2009-06-04T21:46:53.267 回答
1

如果我没记错的话,Acegi 会缓存用户信息。检查“ DefaultSecurityConfig”文件(我认为这是 config/ 下的名称)以禁用用户信息缓存。您还可以在 authenticateService 上调用一些方法(现在不记得是什么方法)来驱逐用户缓存。

您也许可以在UserController#update闭包中找到后者。

于 2009-06-03T16:58:22.803 回答
0

您必须重置经过身份验证的用户。下面的代码就是这样做的(来自这个博客)。

import org.springframework.security.context.SecurityContextHolder
import org.springframework.security.providers.UsernamePasswordAuthenticationToken
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserImpl
import org.springframework.security.GrantedAuthority
import org.springframework.security.GrantedAuthorityImpl

...

def refreshAuthenticatedUser(user) {
    GrantedAuthority[] auths = user.authorities.collect {
        new GrantedAuthorityImpl(it.authority)
    }
    def grailsUser = new GrailsUserImpl(
            user.username,
            "",
            user.enabled,
            true,
            true,
            true,
            auths,
            user)
    def authToken = new UsernamePasswordAuthenticationToken(grailsUser, '', auths)
    SecurityContextHolder.context.authentication = authToken

}
于 2010-03-10T12:20:57.850 回答