Grails Spring Security 插件身份验证失败

Posted

技术标签:

【中文标题】Grails Spring Security 插件身份验证失败【英文标题】:Grails Spring Security Plugin Authentication Fails 【发布时间】:2013-11-13 15:09:30 【问题描述】:

我正在尝试配置 spring-security 2.0-RC2 插件以与我的 Grails 应用程序一起使用。我可以让它将我的默认管理员用户和哈希密码插入到 mongodb 中。我还配置了 spring security 以使用emailAddress 而不是username 作为用户名字段进行身份验证。

当我尝试登录(使用正确的凭据)时,我收到了身份验证失败错误。我对自己做错了什么感到有些困惑。我可能错过了一些导致它不起作用的小东西。我的配置包括在下面。

Config.groovy我有标准配置并指定usernamePropertyName指向电子邮件地址字段而不是用户名。

grails.plugin.springsecurity.userLookup.userDomainClassName = 'model.Person'
grails.plugin.springsecurity.userLookup.usernamePropertyName='email'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'model.PersonRole'
grails.plugin.springsecurity.authority.className = 'model.Role'
grails.plugin.springsecurity.securityConfigType = SecurityConfigType.InterceptUrlMap

//Configure URL Restrictions
grails.plugin.springsecurity.interceptUrlMap = [
  '/login/**':         [
    'IS_AUTHENTICATED_ANONYMOUSLY'
  ],
  '/static/**':        [
    'IS_AUTHENTICATED_ANONYMOUSLY'
  ],
  '/**':               [
    'IS_AUTHENTICATED_REMEMBERED']
]

grails.plugin.springsecurity.password.algorithm = 'SHA-256'

然后我有一个由 spring security 生成的Person.groovy 文件,然后修改为将用户名更改为电子邮件地址。生成的PersonRole.groovyRole.groovy 没有被修改过。

package model

class Person 
  transient springSecurityService

  String id
  String firstName
  String lastName
  String emailAddress
  String password

  boolean enabled = true
  boolean accountExpired
  boolean accountLocked
  boolean passwordExpired

  static transients = ['springSecurityService']

  static constraints = 
    emailAddress blank: false, unique: true
    password blank: false
  

  static mapping =  password column: '`password`' 

  Set<Role> getAuthorities() 
    PersonRole.findAllByPerson(this).collect  it.role  as Set
  

  def beforeInsert() 
    encodePassword()
  

  def beforeUpdate() 
    if (isDirty('password')) 
      encodePassword()
    
  

  protected void encodePassword() 
    password = springSecurityService.encodePassword(password)
  

在我的BootStrap.groovy 中,我创建了一个默认管理员用户,除非已经存在:

def adminUser = Person.findByEmailAddress('admin@test.com') ?: new Person(
    firstName: 'Admin',
    lastName: 'User',
    emailAddress: 'admin@test.com',
    password: springSecurityService.encodePassword('admin'),
    enabled: true).save(failOnError: true)

我还创建了一个自定义auth.gsp 文件,如下所示,但我也尝试使用默认文件,结果相同。

<form action="$postUrl" method="POST" autocomplete="off">
   <h4>Sign in</h4>
   <g:if test="$flash.message">
      <div class="alert alert-danger" style="padding: 10px">$flash.message</div>
   </g:if>
   <p>
     <input type="email" class="form-control" placeholder="Email address" name="j_username" autofocus />
   </p>
   <p>
     <input type="password" class="form-control" placeholder="Password" name="j_password" />
   </p>
   <input type="submit" class="btn btn-lg btn-primary btn-block" value="$message(code: 'springSecurity.login.button')" />
 </form>

那么,有没有人看到我遗漏的任何东西会阻止身份验证工作?

【问题讨论】:

属性是 emailAddress 而不是 email 就像你在你的配置中那样 啊,很好,我重构并忘记更改那里的设置。我的问题是这个和接受的答案的结合。谢谢! 【参考方案1】:

您正在对密码进行双重编码。它在beforeInsertPerson 类中完成,您在BootStrap 代码中再次执行此操作。改变

password: springSecurityService.encodePassword('admin'),

password: 'admin',

【讨论】:

谢谢!我知道我必须做一些我忽略的愚蠢的事情。我没有足够关注生成的代码与我发现的作为 BootStrap 类示例的代码相关的功能。 另外,正如另一条评论中指出的那样,我没有正确设置 usernamePropertyName 属性。

以上是关于Grails Spring Security 插件身份验证失败的主要内容,如果未能解决你的问题,请参考以下文章

Grails,Spring Security LDAP 插件

在 grails 中使用 spring-security 插件时出错

使用 Spring Security Grails 插件编码密码

Grails - 卸载 Spring Security Core

通过 Spring Security 配置 Grails 配置插件 grails-ckeditor

带有 grails 的 Spring Security 核心插件