Spring安全角色Grails无法识别域类

时间:2016-10-21 08:15:43

标签: grails spring-security

我是grails的新手,我使用grails 3.1.11编写使用spring security 3.1.1保护的API。我正在使用Document DB来保存数据。

使用插件命令我创建了域类

grails s2-quickstart com.documentstore.domain User Role

在所需的包中生成了User.groovy,Role.groovy,UserRole.groovy和application.groovy类。我修改了Bootstrap.groovy如下:

import com.documentstore.domain.Role
import com.documentstore.domain.User
import com.documentstore.domain.UserRole

class BootStrap {

    def init = { servletContext ->
        def role = new Role(authority: 'ROLE_USER')
        role.save()

        def me = new User(username : 'vamsi', password : 'password')
        me.save()

        UserRole.create(me, role)

        UserRole.withSession {
            it.flush()
            it.clear()
        }
    }
    def destroy = {
    }
}

当我尝试运行应用程序时,我得到了域类无法识别的错误:

    ERROR org.springframework.boot.SpringApplication - Application startup failed
java.lang.IllegalStateException: Either class [com.documentstore.domain.Role] is not a domain class or GORM has not been initialized correctly or has already been shutdown. If you are unit testing your entities using the mocking APIs
    at org.grails.datastore.gorm.GormEnhancer.stateException(GormEnhancer.groovy:161)
    at org.grails.datastore.gorm.GormEnhancer.findInstanceApi(GormEnhancer.groovy:167)
    at org.grails.datastore.gorm.GormEnhancer.findInstanceApi(GormEnhancer.groovy)
    at org.grails.datastore.gorm.GormEntity$Trait$Helper.currentGormInstanceApi(GormEntity.groovy:1322)
    at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:98)
    at org.grails.datastore.gorm.GormEntity$Trait$Helper$save.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at com.documentstore.domain.Role.save(Role.groovy)
    at com.documentstore.domain.Role.save(Role.groovy)
    at org.grails.datastore.gorm.GormEntity$save.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
    at BootStrap$_closure1.doCall(BootStrap.groovy:9)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1089)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
    at groovy.lang.Closure.call(Closure.java:414)
    at groovy.lang.Closure.call(Closure.java:408)

代码有问题吗?怎么解决这个问题?

指定build.gradle和插件生成的代码以供参考:

Build.gradle

dependencies {

compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-dependencies"
compile "org.grails:grails-web-boot"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:scaffolding"
console "org.grails:grails-console"
compile "org.grails.plugins:spring-security-core:3.1.1"
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage
compile group: 'com.microsoft.azure', name: 'azure-storage', version: '4.3.0'
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-documentdb
compile group: 'com.microsoft.azure', name: 'azure-documentdb', version: '1.8.1'
profile "org.grails.profiles:web"
runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.8.2"
//runtime "com.h2database:h2"
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-documentdb
runtime group: 'com.microsoft.azure', name: 'azure-storage', version: '4.3.0'
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails.plugins:geb"
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"

}

Role.groovy

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@ToString(includes='authority', includeNames=true, includePackage=false)
class Role implements Serializable {
private static final long serialVersionUID = 1

String authority

static constraints = {
    authority blank: false, unique: true
}

static mapping = {
    cache true
}
}

User.groovy

package com.documentstore.domain

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {
private static final long serialVersionUID = 1

transient springSecurityService

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

User(String username, String password) {
    this()
    this.username = username
    this.password = password
}

Set<Role> getAuthorities() {
    UserRole.findAllByUser(this)*.role
}

def beforeInsert() {
    encodePassword()
}

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

protected void encodePassword() {
    password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}

static transients = ['springSecurityService']

static constraints = {
    username blank: false, unique: true
    password blank: false
}

static mapping = {
    password column: '`password`'
}

}

UserRole.groovy

package com.documentstore.domain

import grails.gorm.DetachedCriteria
import groovy.transform.ToString

import org.apache.commons.lang.builder.HashCodeBuilder

@ToString(cache=true, includeNames=true, includePackage=false)
class UserRole implements Serializable {
private static final long serialVersionUID = 1

User user
Role role

UserRole(User u, Role r) {
    this()
    user = u
    role = r
}

@Override
boolean equals(other) {
    if (!(other instanceof UserRole)) {
        return false
    }

    other.user?.id == user?.id && other.role?.id == role?.id
}

@Override
int hashCode() {
    def builder = new HashCodeBuilder()
    if (user) builder.append(user.id)
    if (role) builder.append(role.id)
    builder.toHashCode()
}

static UserRole get(long userId, long roleId) {
    criteriaFor(userId, roleId).get()
}

static boolean exists(long userId, long roleId) {
    criteriaFor(userId, roleId).count()
}

private static DetachedCriteria criteriaFor(long userId, long roleId) {
    UserRole.where {
        user == User.load(userId) &&
        role == Role.load(roleId)
    }
}

static UserRole create(User user, Role role, boolean flush = false) {
    def instance = new UserRole(user: user, role: role)
    instance.save(flush: flush, insert: true)
    instance
}

static boolean remove(User u, Role r, boolean flush = false) {
    if (u == null || r == null) return false

    int rowCount = UserRole.where { user == u && role == r }.deleteAll()

    if (flush) { UserRole.withSession { it.flush() } }

    rowCount
}

static void removeAll(User u, boolean flush = false) {
    if (u == null) return

    UserRole.where { user == u }.deleteAll()

    if (flush) { UserRole.withSession { it.flush() } }
}

static void removeAll(Role r, boolean flush = false) {
    if (r == null) return

    UserRole.where { role == r }.deleteAll()

    if (flush) { UserRole.withSession { it.flush() } }
}

static constraints = {
    role validator: { Role r, UserRole ur ->
        if (ur.user == null || ur.user.id == null) return
        boolean existing = false
        UserRole.withNewSession {
            existing = UserRole.exists(ur.user.id, r.id)
        }
        if (existing) {
            return 'userRole.exists'
        }
    }
}

static mapping = {
    id composite: ['user', 'role']
    version false
}

}

1 个答案:

答案 0 :(得分:1)

这是因为spring security和spring security rest插件依赖于hibernate,ehcache和h2数据库jar。因为我使用的是不同的数据库,所以我删除了这些jar依赖项。在我将这些jar包含为运行时依赖项并修改application.yml以包含这些数据源的默认配置之后,所有内容都按预期工作正常。