使用 Spring Security Grails 插件进行授权

发布于 2024-12-07 15:24:38 字数 1428 浏览 0 评论 0原文

背景

我正在使用 Spring Security Grails 插件。因为我的 User 和 Role 类不是 GORM 对象,所以我用自己的实现替换了插件提供的 UserDetailsS​​ervice

class CustomUserDetailsService implements UserDetailsService {

    static transactional = false
    private static final log = LogFactory.getLog(this)

    @Autowired
    private UserManager userManager

    @Autowired
    private RoleManager roleManager

    UserDetails loadUserByUsername(String username) {
        User user = userManager.getUserByEmail(username)
        UserDetails userDetails = new UserAdapter(user, roleManager)

        log.debug "user '$username' has roles: ${userDetails.authorities?.authority}"
        userDetails       
    }
}

问题

当我登录时,我看到从 记录了以下消息CustomUserDetailsS​​ervice.loadUserByUsername()

用户“[电子邮件受保护]”的角色:[USER]

所以看起来该用户已被分配 USER 角色。但是,当我尝试访问该控制器的操作时:

@Secured(['ROLE_USER', 'ROLE_ADMINISTRATOR'])
class MyProfileController {
    def someAction = { // impl omitted }
}

我被弹回访问被拒绝页面。我非常确定用户已登录,因为访问被拒绝的页面包含诸如之类的标记

<sec:ifLoggedIn>
  protected content
</sec:ifLoggedIn>

,并且显示了受保护的内容。因此,当执行控制器授权时,用户角色似乎与当前用户没有关联。日志消息表明 UserDetailsS​​ervice 正常。

Background

I'm using the Spring Security Grails plugin. Because my User and Role classes are not GORM objects, I I've replaced the UserDetailsService provided by the plugin with my own implementation:

class CustomUserDetailsService implements UserDetailsService {

    static transactional = false
    private static final log = LogFactory.getLog(this)

    @Autowired
    private UserManager userManager

    @Autowired
    private RoleManager roleManager

    UserDetails loadUserByUsername(String username) {
        User user = userManager.getUserByEmail(username)
        UserDetails userDetails = new UserAdapter(user, roleManager)

        log.debug "user '$username' has roles: ${userDetails.authorities?.authority}"
        userDetails       
    }
}

Problem

When I login, I see the following message is logged from CustomUserDetailsService.loadUserByUsername()

user '[email protected]' has roles: [USER]

So it seems that the user has been assigned the USER role. However, when I then try and access an action of this controller:

@Secured(['ROLE_USER', 'ROLE_ADMINISTRATOR'])
class MyProfileController {
    def someAction = { // impl omitted }
}

I get bounced to the access denied page. I'm pretty sure that the user is logged in, because the access denied page contains markup such as

<sec:ifLoggedIn>
  protected content
</sec:ifLoggedIn>

and the protected content is displayed. So it seems that somehow the USER role is not associated with the current user, when the controller authorisation is performed. The log message suggests that the UserDetailsService is OK.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长梦不多时 2024-12-14 15:24:38

解决方案

解决方案是确保域类/数据库中的角色名称以“ROLE_”开头,根据注释参数。

致谢

该答案的所有功劳都归功于@BurtBeckwith 和@tim_yates,他们在评论中提供了解决方案。我正在将他们的评论转换为答案,因为未来的读者可能很容易错过他们的评论。

Solution

The solution is to make sure that the role names in the domain class/database begin with "ROLE_", as per the annotation parameters.

Acknowledgements

All credit for this answer goes to @BurtBeckwith and @tim_yates, who provided the solution in comments. I'm converting their comments to an answer, as future readers may easily miss their comments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文