grails 3.3 spring security beforeinsert在哪里加密密码?

时间:2019-01-28 21:09:29

标签: grails spring-security

要将身份验证添加到grails 3应用程序,请将其添加到build.gradle:

compile 'org.grails.plugins:spring-security-core:3.2.3'

然后运行

 grails s2-quickstart com.myapp Operator Role

这将创建3个域对象,但我找不到其他对象。

Operator域对象如下:

package com.myapp

importgroovy.transform.EqualsAndHashCode
importgroovy.transform.ToString
importgrails.compiler.GrailsCompileStatic

@GrailsCompileStatic
@EqualsAndHashCode(includes='username')
@ToString(includes='username',includeNames=true,includePackage=false)
classOperatorimplementsSerializable{

privatestaticfinallongserialVersionUID=1

Stringusername
Stringpassword
booleanenabled=true
booleanaccountExpired
booleanaccountLocked
booleanpasswordExpired

Set<Role>getAuthorities(){
(OperatorRole.findAllByOperator(this)asList<OperatorRole>)*.roleasSet<Role>
}

staticconstraints={
passwordnullable:false,blank:false,password:true
usernamenullable:false,blank:false,unique:true
}

staticmapping={
passwordcolumn:'
`password`'
}
}

问题是,缺少插入之前的加密密码。在grails 2.5中,它曾经将其放入Operator域对象:

    def beforeInsert() {
            encodePassword()
    }

因此,我希望密码以纯文本形式插入,但似乎并非如此。至少对于使用bootstrap创建的操作员而言,它似乎已加密。问题是在哪里以及如何使用?

2 个答案:

答案 0 :(得分:3)

允许域类进行自动装配并将Bean注入域类的每个实例的旧方法花费了大量的内存。更高版本的Grails(3.3.x)选择使用PreInsertEvent侦听器对密码进行编码。这样可以节省大量内存,同时获得相同的结果。请参阅s2quicktstart的文档以及在您的应用中创建的类UserPasswordEncoderListener

https://grails-plugins.github.io/grails-spring-security-core/latest/index.html#tutorials

答案 1 :(得分:0)

编码密码的另一种方法是将方法注入Application.groovy。

我的UserAccont类:

class UserAccount {

  //.. fields 

  def beforeInsert() {
    encodePassword()
  }

  def beforeUpdate() {
    encodePassword()
  }

  String encodePassword() {
    throw new UnsupportedOperationException('Not implemented password encoder!' )
  }
}

注入看起来像:

class Application extends GrailsAutoConfiguration {

  @Override
  void doWithDynamicMethods() {
    SpringSecurityService springSecurityService = applicationContext.getBean 'springSecurityService'
    UserAccount.metaClass.encodePassword = {-> 
      delegate.password = springSecurityService.encodePassword delegate.password
    }
  }
}

在这种情况下,我不必在GORM实体中提供@Autowire服务。在我的应用程序中,我还可以使用来自另一个基于GORM-standalode的模块的域类,而该模块没有SpringSec依赖性。