我正在将SpringSecurity插件与应用程序集成。为此,我安装了插件并运行了s2-quickstart脚本,该脚本创建了三个域类:SecUser
,SecRole
和SecUserSecRole
以及登录/注销控制器。< / p>
由于我已经有一个现有的用户域类,并希望保留它,我修改了User以扩展SecUser并从User中删除了用户名和密码的重叠字段。另外,我已将tablePerHierarchy false
添加到User和SecUser映射部分。
在BootStrap中,我正在尝试创建一个在启动时存在的Admin用户。为此,我创建了一个新的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的约束为blank:false,如果我在创建User实例时注释掉userType字段,我会得到一个句子,指出null不是userType的有效设置。当我包含它时,我得到瞬态对象异常:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例:books4africa.SecUser ,所以我知道我正在通过所有用户验证设置。 / p>
是什么原因导致在这种情况下无法保存有效的User对象?
修改
此问题的解决方案是删除现有的dev数据库文件并重新初始化应用程序。我的猜测是db和Spring Security与原始数据库之间存在某种冲突,因此用新数据库重新启动应用程序解决了这个问题。
由于下面的答案都没有解决确切的问题,在这种情况下我不会接受,但感谢您的帮助!
答案 0 :(得分:1)
您没有说出瞬态实例的类型(用户或角色)。在您创建管理员角色时,是否在尝试为新管理员用户授予此角色之前保存它?我在上面的代码中没有看到这一部分。
答案 1 :(得分:1)
对我而言,这似乎是域名的问题或者您创建实例的方式。
你说:
我修改了用户以扩展SecUser并删除了重叠字段 来自用户的用户名和密码。另外,我添加了tablePerHierarchy 用户和SecUser映射部分均为false。
但也许你没有告诉插件你这样做了。请看看documentation regarding the domain classes。要使用您自己的域,您必须配置SpringSecurity插件(该文档包含您需要的所有信息)。因此,例如,如果您想使用自己的用户类。你在你的配置上放了这样的东西:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'your.package.NameOfYourClass'
这将告诉插件它必须为用户使用的类是NameOfYourClass
。
使用默认类非常重要,例如,生成的快速入门是正确使用自定义用户和角色类的最简单方法(只需将每个属性复制到您自己的类中,并根据需要重命名)
另请查看tutorials,了解如何正确保存用户和角色。