Grails 弹簧安全/Acegi。自定义用户 +密码过期管理
我正在开发一个 Grails 遗留项目。存在一个名为 User 的域类。它包含密码、用户名、角色等。
本项目使用Spring Security进行角色管理。我想添加凭据过期(强制用户更新其密码)。
我修改了 User 类。不是它实现了 用户详细信息界面。
但是,当我启动服务器时,出现此错误>
org.springframework.beans.factory.BeanCreationException: 使用名称创建 bean 时出错 “messageSource”:初始化 豆失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:
使用名称创建 bean 时出错 “transactionManager”:无法解析 引用 bean 'sessionFactory' 设置bean属性时 '会话工厂';嵌套异常是 org.springframework.beans.factory.BeanCreationException:
使用名称创建 bean 时出错 'sessionFactory':调用 init 方法失败;嵌套异常是 org.hibernate.PropertyNotFoundException:
找不到属性的 setter 课堂上的 accountNonExpired com.company.app.user.User
我必须注册一些bean吗?我发现该错误非常令人困惑,因为该接口不需要设置方法。
更新
经过更多调查后,我遇到了我的 SecurityConfig.groovy,它看起来很多像这样(AcegiSecurity Plugin):
security {
// see DefaultSecurityConfig.groovy for all settable/overridable properties
active = true
loginUserDomainClass = "User"
authorityDomainClass = "Role"
....
}
我的 User 类也看起来很多像这样:
/**
* User domain class.
*/
class User {
static transients = ['pass','passwordExpired','credentialsNonExpired']
static hasMany = [authorities: Role]
static belongsTo = Role
/** Username */
String username
/** User Real Name*/
String userRealName
/** MD5 Password */
String passwd
/** enabled */
boolean enabled
String email
boolean emailShow
/** description */
String description = ''
/** plain password to create a MD5 password */
String pass = '[secret]'
static constraints = {
username(blank: false, unique: true)
userRealName(blank: false)
passwd(blank: false)
enabled()
}
public boolean isCredentialsNonExpired() {
return true;
}
}
我添加了一个方法来检查密码是否此类(isCredentialsNonExpired)是否应过期
。我需要这个方法在登录时执行。现在,还不是。
所以看起来这是我应该采取的 Acegi 方法。有什么想法吗?据我了解,Acegi 使用 Spring Security,对吗?
I'm working on a grails legacy project. A domain class called User exists. It contains password, username, roles, etc.
This project uses Spring Security for role management. I would like to add expiration of credentials ( force the User to renew its password).
I've modified the User class. Not it implements the UserDetails interface.
However, when I start the server, I get this error>
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'messageSource': Initialization of
bean failed; nested exception is
org.springframework.beans.factory.BeanCreationException:Error creating bean with name
'transactionManager': Cannot resolve
reference to bean 'sessionFactory'
while setting bean property
'sessionFactory'; nested exception is
org.springframework.beans.factory.BeanCreationException:Error creating bean with name
'sessionFactory': Invocation of init
method failed; nested exception is
org.hibernate.PropertyNotFoundException:Could not find a setter for property
accountNonExpired in class
com.company.app.user.User
Do I have to register some bean? I find the error quite confusing, since the interface doesn't asks for a setter method.
update
After investigating some more, I ran into my SecurityConfig.groovy, that looks A LOT like this (AcegiSecurity Plugin):
security {
// see DefaultSecurityConfig.groovy for all settable/overridable properties
active = true
loginUserDomainClass = "User"
authorityDomainClass = "Role"
....
}
My User class also looks A LOT like this:
/**
* User domain class.
*/
class User {
static transients = ['pass','passwordExpired','credentialsNonExpired']
static hasMany = [authorities: Role]
static belongsTo = Role
/** Username */
String username
/** User Real Name*/
String userRealName
/** MD5 Password */
String passwd
/** enabled */
boolean enabled
String email
boolean emailShow
/** description */
String description = ''
/** plain password to create a MD5 password */
String pass = '[secret]'
static constraints = {
username(blank: false, unique: true)
userRealName(blank: false)
passwd(blank: false)
enabled()
}
public boolean isCredentialsNonExpired() {
return true;
}
}
I added a method to check if the password should expire or not for this class (isCredentialsNonExpired)
. I need this method to execute at login. Right now, its not.
So it looks like it's the Acegi approach I should take. Any thoughts? Its my understanding that Acegi uses Spring Security, right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你是使用Acegi插件,还是直接配置它?如果您使用 Spring Security Core 插件,这会容易得多,因为它受以下支持盒子。
您可能不希望您的 User 类成为您的 UserDetailsService 类,因为它通常还有其他包袱,例如映射集合等。它当然可以工作,但创建一个简单的数据类是更好的方法。根据 Spring Security 的版本,可以方便地对 org.springframework.security.userdetails.User 或 org.springframework.security.core.userdetails.User 进行子类化。
看起来您刚刚为 accountNonExpired 添加了一个 getter,但如果要持久保存它,那么它也需要一个 setter。如果您正在导出该值并且不希望该字段位于数据库中,那么您可以将其添加到瞬态列表中:
Are you using the Acegi plugin, or configuring it directly? If you use the Spring Security Core plugin this will be a lot easier since it's supported out of the box.
You probably don't want your User class to be your UserDetailsService class since it often has other baggage like mapped collections, etc. It can certainly work, but creating a simple data class is a better approach. It's convenient to subclass org.springframework.security.userdetails.User or org.springframework.security.core.userdetails.User depending on the version of Spring Security.
It looks like you just added a getter for accountNonExpired but if it's going to be persisted then it needs a setter too. If you're deriving the value and don't want that field to be in the database then you can add it to the transients list: