0

我正在做一个 grails 遗留项目。存在一个名为 User 的域类。它包含密码、用户名、角色等。

本项目使用 Spring Security 进行角色管理。我想添加凭据到期(强制用户更新其密码)。

我已经修改了 User 类。不是它实现了UserDetails 接口

但是,当我启动服务器时,我收到此错误>

org.springframework.beans.factory.BeanCreationException:创建名为“messageSource”的bean时出错:bean初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:

创建名为“transactionManager”的bean时出错:设置bean属性“sessionFactory”时无法解析对bean“sessionFactory”的引用;嵌套异常是 org.springframework.beans.factory.BeanCreationException:

创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.PropertyNotFoundException:

在 com.company.app.user.User 类中找不到属性 accountNonExpired 的设置器

我必须注册一些bean吗?我发现这个错误非常令人困惑,因为该界面不要求使用 setter 方法。

更新

在调查了更多之后,我遇到了我的 SecurityConfig.groovy,它看起来很像这样(AcegiSecurity插件):

security {
   // see DefaultSecurityConfig.groovy for all settable/overridable properties

   active = true

   loginUserDomainClass = "User"
   authorityDomainClass = "Role"

 ....
}

我的用户类也看起来很像这样:

/**
 * 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,对吗?

4

1 回答 1

3

您是使用 Acegi 插件,还是直接配置它?如果您使用Spring Security Core插件,这将容易得多,因为它是开箱即用的。

您可能不希望您的 User 类成为您的 UserDetailsS​​ervice 类,因为它通常有其他包袱,如映射集合等。它当然可以工作,但创建一个简单的数据类是一种更好的方法。根据 Spring Security 的版本,子类化 org.springframework.security.userdetails.User 或 org.springframework.security.core.userdetails.User 很方便。

看起来您刚刚为 accountNonExpired 添加了一个 getter,但如果它要被持久化,那么它也需要一个 setter。如果您正在派生该值并且不希望该字段位于数据库中,那么您可以将其添加到瞬态列表中:

static transients = ['accountNonExpired']
于 2010-10-05T15:12:47.987 回答