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...

下面