GRAILS + Spring Security Plugin --- 添加用户时密码未加密
GRAILS + Spring Security Plugin --- password is not encrypted when adding users
全新安装 Grails 3.2.9 + Spring 安全插件 3.1.0。
s2-quickstart com.raf.app User Role
.
创建的默认 User/Role/UserRole 个域
BootStrap 初始化代码:
...
def init = { servletContext ->
def adminRole = Role.findOrSaveWhere(authority: 'ROLE_ADMIN')
def user = User.findOrSaveWhere(username: 'raf',
password: 'password')
if (!user.authorities.contains(adminRole)){
UserRole.create(user, adminRole)
}
...
我在教程中看到这个用户的密码应该在数据库中编码(使用 dbconsole 来检查),但在我的情况下它没有(它只是 'password' 就像这里一样) .
所以我转到用户域并进行了这些可怕的更改:
def beforeUpdate() {
encodePassword()
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : springSecurityService.encodePassword(password)
}
另一方面,这会引发 NullPointer 异常。为什么?
Cannot invoke method encodePassword() on null object
那么我该怎么做才能像我喜欢的那样加密我的密码?
所以解释一下发生了什么,希望它更有意义
您只是告诉代码如果找不到编码就重复加密函数。
以上代码默认在此处
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
这是说:
if (springSecurityService?.passwordEncoder) {
springSecurityService.encodePassword(password)
} else {
password
}
所以你看你已经告诉它做它不能做的事
我正在使用 grails 3.2.8 并使用:
compile 'org.grails.plugins:spring-security-core:3.1.2'
好的,所以我相信 NullPointer 是由 vahid 描述的内容引起的。
但是,要让我的密码默认编码,我必须设置
autowire: true
在 Configs/application.yml 中。不要问我为什么,但它有效。
如果您手动设置 Spring 安全性而不是使用提供的命令。也许您忘记添加 UserPasswordEncoderListener
class 并在 resources.groovy
中将其定义为 bean。这个class应该自动编码密码
UserPasswordEncoderListener:
import grails.plugin.springsecurity.SpringSecurityService
import groovy.transform.CompileStatic
import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationEvent
@CompileStatic
class UserPasswordEncoderListener extends AbstractPersistenceEventListener {
@Autowired
SpringSecurityService springSecurityService
UserPasswordEncoderListener(final Datastore datastore) {
super(datastore)
}
@Override
protected void onPersistenceEvent(AbstractPersistenceEvent event) {
if (event.entityObject instanceof User) {
User u = (event.entityObject as User)
if (u.password && (event.eventType == EventType.PreInsert || (event.eventType == EventType.PreUpdate && u.isDirty('password')))) {
event.getEntityAccess().setProperty("password", encodePassword(u.password))
}
}
}
@Override
boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
eventType == PreUpdateEvent || eventType == PreInsertEvent
}
private String encodePassword(String password) {
springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}
}
resources.groovy
beans = {
userPasswordEncoderListener(UserPasswordEncoderListener, ref('hibernateDatastore'))
}
UserPasswordEncoderListener
应该放在src/main/groovy/com.mypackage...
下面
全新安装 Grails 3.2.9 + Spring 安全插件 3.1.0。
s2-quickstart com.raf.app User Role
.
BootStrap 初始化代码:
...
def init = { servletContext ->
def adminRole = Role.findOrSaveWhere(authority: 'ROLE_ADMIN')
def user = User.findOrSaveWhere(username: 'raf',
password: 'password')
if (!user.authorities.contains(adminRole)){
UserRole.create(user, adminRole)
}
...
我在教程中看到这个用户的密码应该在数据库中编码(使用 dbconsole 来检查),但在我的情况下它没有(它只是 'password' 就像这里一样) .
所以我转到用户域并进行了这些可怕的更改:
def beforeUpdate() {
encodePassword()
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : springSecurityService.encodePassword(password)
}
另一方面,这会引发 NullPointer 异常。为什么?
Cannot invoke method encodePassword() on null object
那么我该怎么做才能像我喜欢的那样加密我的密码?
所以解释一下发生了什么,希望它更有意义
您只是告诉代码如果找不到编码就重复加密函数。
以上代码默认在此处
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
这是说:
if (springSecurityService?.passwordEncoder) {
springSecurityService.encodePassword(password)
} else {
password
}
所以你看你已经告诉它做它不能做的事
我正在使用 grails 3.2.8 并使用:
compile 'org.grails.plugins:spring-security-core:3.1.2'
好的,所以我相信 NullPointer 是由 vahid 描述的内容引起的。
但是,要让我的密码默认编码,我必须设置
autowire: true
在 Configs/application.yml 中。不要问我为什么,但它有效。
如果您手动设置 Spring 安全性而不是使用提供的命令。也许您忘记添加 UserPasswordEncoderListener
class 并在 resources.groovy
中将其定义为 bean。这个class应该自动编码密码
UserPasswordEncoderListener:
import grails.plugin.springsecurity.SpringSecurityService
import groovy.transform.CompileStatic
import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationEvent
@CompileStatic
class UserPasswordEncoderListener extends AbstractPersistenceEventListener {
@Autowired
SpringSecurityService springSecurityService
UserPasswordEncoderListener(final Datastore datastore) {
super(datastore)
}
@Override
protected void onPersistenceEvent(AbstractPersistenceEvent event) {
if (event.entityObject instanceof User) {
User u = (event.entityObject as User)
if (u.password && (event.eventType == EventType.PreInsert || (event.eventType == EventType.PreUpdate && u.isDirty('password')))) {
event.getEntityAccess().setProperty("password", encodePassword(u.password))
}
}
}
@Override
boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
eventType == PreUpdateEvent || eventType == PreInsertEvent
}
private String encodePassword(String password) {
springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}
}
resources.groovy
beans = {
userPasswordEncoderListener(UserPasswordEncoderListener, ref('hibernateDatastore'))
}
UserPasswordEncoderListener
应该放在src/main/groovy/com.mypackage...