Grails 3.1.7由GORM Scaffolding创建新用户时的Spring Security问题

时间:2016-05-27 20:36:33

标签: grails spring-security spring-security-rest

我正在Grails (版本3.1.7)中做我的第一步,我正在做一个需要用户身份验证的应用程序。这个应用程序是一个Web应用程序,也提供了一些REST功能,所以我需要一个Web登录和一个"休息"用令牌登录。

我正在使用 spring-security-core:3.1.0 spring-security-rest:2.0.0.M2 进行这些建议,两个登录都正常运行

现在,当我尝试通过grails generate-all package.User生成的CRUD创建新用户时,我遇到了一些麻烦,我正确生成了视图(我有一个客户端类,用户可以拥有或不拥有,如果用户有它我也在同一个创建部分提供客户端字段,因为客户端只能有一个用户)。当我保存它时,我收到内部服务器错误500:

URI / web / webUser / save Class java.lang.NullPointerException 讯息 null

文件中的

\ web \ WebUserController.groovy 该行是: webUser.save flush:true

跟踪是:

Line | Method
80 | doFilter  in grails.plugin.springsecurity.rest.RestLogoutFilter
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|     64 | doFilter  in grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter
|     53 | doFilter  in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
|    143 | doFilter  in grails.plugin.springsecurity.rest.RestAuthenticationFilter
|     62 | doFilter  in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
|     58 | doFilter  in grails.plugin.springsecurity.web.SecurityRequestHolderFilter
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run . . . in java.lang.Thread

Caused by NullPointerException: null
->>   47 | $tt__save in WebUserController.groovy
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|     96 | doInTransaction in grails.transaction.GrailsTransactionTemplate$2
|     93 | execute . in grails.transaction.GrailsTransactionTemplate
|     96 | doInTransaction in grails.transaction.GrailsTransactionTemplate$2
|     93 | execute . in grails.transaction.GrailsTransactionTemplate
|     80 | doFilter  in grails.plugin.springsecurity.rest.RestLogoutFilter
|     64 | doFilter  in  grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter
|     53 | doFilter  in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
|    143 | doFilter  in grails.plugin.springsecurity.rest.RestAuthenticationFilter
|     62 | doFilter  in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
|     58 | doFilter  in grails.plugin.springsecurity.web.SecurityRequestHolderFilter
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run       in java.lang.Thread

我不确定安全插件配置或用户和客户端域类或userController中是否有问题。

编辑:提升信息!

@Transactional(readOnly = true)

class WebUserController {

static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
static namespace = 'web'

def springSecurityService
@Transactional
def save(WebUser webUser) {
    if (webUser == null) {
        transactionStatus.setRollbackOnly()
        notFound()
        return
    }

    if (webUser.hasErrors()) {
        transactionStatus.setRollbackOnly()
        respond webUser.errors, view:'create'
        return
    }

    webUser.save flush:true // line where the NullPointerException is threw 

    if (webUser.isAdmin){
        UserRole.create webUser, Role.findByAuthority('ROLE_ADMIN')
    } else {
        UserRole.create webUser, Role.findByAuthority('ROLE_CLIENT')
    }

    request.withFormat {
        form multipartForm {
            flash.message = message(code: 'default.created.message', args: [message(code: 'webUser.label', default: 'WebUser'), webUser.id])
            redirect webUser
        }
        '*' { respond webUser, [status: CREATED] }
    }
}

and domin中的代码:

transient springSecurityService

String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired

static transients = ['isAdmin', 'springSecurityService']
boolean isAdmin
Client client
String name
String email
Date lastVisit
static hasMany = [orders: BOrder]

static constraints = {
    username size: 5..15, blank: false, unique: true
    password size: 5..15, blank: false, password: true
    email email: true, blank: false, unique: true
    name size: 0..50, nullable: true
    lastVisit nullable: true
    client nullable: true
}

当客户端为null或不为null时,会发生错误。调试如果我在WebUser域类中添加一个afterInsert,我可以看到生成的客户端ID,如果它不是null,但是没有生成WebUser id,那时我没有看到任何错误消息。

1 个答案:

答案 0 :(得分:1)

我发现问题出在哪里。

问题是我在密码大小上添加了一个约束,并且在密码被哈希之前执行了验证,因此验证通过,然后密码被哈希并且它不会少于15个字符,所以当它试图将用户持久保存在数据库中然后它抛出空指针异常时失败了。

删除或更改密码的最大长度限制,问题已解决。

对我来说唯一奇怪的是我得到的错误信息,在我看来并没有说明任何相关内容。