1

我正在将 SpringSecurity 插件与应用程序集成。为此,我安装了插件并运行了 s2-quickstart 脚本,该脚本创建了三个域类:SecUserSecRoleSecUserSecRole以及登录/注销控制器。

由于我已经有一个现有的 User 域类并想保留它,所以我修改了 User 以扩展 SecUser 并从 User 中删除了用户名和密码的重叠字段。此外,我还添加tablePerHierarchy false了 User 和 SecUser 映射部分。

在 BootStrap 中,我正在尝试创建一个管理员用户以在启动时存在。为此,我创建了一个新SecRole对象 adminRole,其权限设置为 ROLE_ADMIN。然后,我创建一个新的 User 对象并通过以下方式检查它是否包含管理员角色

def springSecurityService
def init {
    def adminUser = User.findByUsername('admin') ?: new User(
        username:'admin',
        password:'adminUser',
        userType:'Admin',
        enabled:true    
    ).save(failOnError:true)

    if (!adminUser.authorities.contains(adminRole))
        SecUserSecRole.create adminUser, adminRole, true

}

我的问题是,无论 adminUser 是否被声明为 User 或 SecUser 实例,我都会不断收到瞬态实例异常。由于 userType 有一个空白约束:false,如果我在创建 User 实例时注释掉 userType 字段,我会得到一个异常,指出 null 不是 userType 的有效设置。当我包含它时,我得到了瞬态对象异常:对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例: books4africa.SecUser,所以我知道我正在通过所有用户验证设置。

是什么导致在这种情况下无法保存有效的用户对象?

编辑

此问题的解决方案是删除现有的开发数据库文件并重新初始化应用程序。我的猜测是数据库和 Spring Security 与原始数据库之间存在某种冲突,因此使用新数据库重新启动应用程序解决了这个问题。

由于以下答案都没有解决确切的问题,因此在这种情况下我不会接受,但感谢您的帮助!

4

2 回答 2

1

您没有说瞬态实例是什么类型(用户或角色)。当您创建管理员角色时,您是否在尝试为新管理员用户提供此角色之前保存它?我在上面的代码中看不到那部分。

于 2012-04-26T03:21:18.143 回答
1

对我来说,这似乎是域或创建它们实例的方式的问题。

你说:

我修改了 User 以扩展 SecUser 并从 User 中删除了用户名和密码的重叠字段。另外,我在 User 和 SecUser 映射部分都添加了 tablePerHierarchy false。

但也许你没有告诉插件你这样做了。请查看有关域类的文档。要使用您自己的域,您必须配置 SpringSecurity 插件(文档包含您需要的所有信息)。因此,例如,如果您想使用自己的用户类。你把这样的东西放在你的配置上:

grails.plugins.springsecurity.userLookup.userDomainClassName = 'your.package.NameOfYourClass'

这将告诉插件它必须为用户使用的类是NameOfYourClass.

使用默认类很重要,例如,生成的快速入门是正确使用自定义用户和角色类的最简单方法(只需将每个属性复制到您自己的类中,并根据需要重命名)。

并查看教程,了解如何正确保存用户和角色。

于 2012-04-26T16:23:37.350 回答