一个组件需要一个名为 '' 的 bean,但无法找到

Posted

技术标签:

【中文标题】一个组件需要一个名为 \'\' 的 bean,但无法找到【英文标题】:A component required a bean named '' that could not be found一个组件需要一个名为 '' 的 bean,但无法找到 【发布时间】:2017-10-05 21:33:12 【问题描述】:

我正在尝试按照this post 的说明使用 grails-spring-security-rest 插件构建我的第一个 grails 应用程序。

但是,当我尝试运行应用程序时,它会给出以下输出:

| Running application...
2017-05-07 20:18:54.614  WARN --- [           main] g.p.s.SpringSecurityCoreGrailsPlugin     : 
Configuring Spring Security Core ...

Configuring Spring Security Core ...
2017-05-07 20:18:54.688  WARN --- [           main] g.p.s.SpringSecurityCoreGrailsPlugin     : ... finished configuring Spring Security Core

... finished configuring Spring Security Core


Configuring Spring Security REST 2.0.0.M2...
... finished configuring Spring Security REST

        ... with GORM support
2017-05-07 20:19:00.278 DEBUG --- [ost-startStop-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Validated configuration attributes
2017-05-07 20:19:00.527 DEBUG --- [ost-startStop-1] g.p.s.r.t.g.jwt.FileRSAKeyProvider       : Loading public/private key from DER files
2017-05-07 20:19:00.531 DEBUG --- [ost-startStop-1] g.p.s.r.t.g.jwt.FileRSAKeyProvider       : Public key path: /mnt/dev/Workspaces/LZR.RAS/RAS-API/security/public_key.der
2017-05-07 20:19:00.538 DEBUG --- [ost-startStop-1] g.p.s.r.t.g.jwt.FileRSAKeyProvider       : Private key path: /mnt/dev/Workspaces/LZR.RAS/RAS-API/security/private_key.der
2017-05-07 20:19:00.612 DEBUG --- [ost-startStop-1] g.p.s.rest.RestTokenValidationFilter     : Initializing filter 'restTokenValidationFilter'
2017-05-07 20:19:00.612 DEBUG --- [ost-startStop-1] g.p.s.rest.RestTokenValidationFilter     : Filter 'restTokenValidationFilter' configured successfully
2017-05-07 20:19:00.612 DEBUG --- [ost-startStop-1] o.s.s.w.a.ExceptionTranslationFilter     : Initializing filter 'restExceptionTranslationFilter'
2017-05-07 20:19:00.612 DEBUG --- [ost-startStop-1] o.s.s.w.a.ExceptionTranslationFilter     : Filter 'restExceptionTranslationFilter' configured successfully
2017-05-07 20:19:00.613 DEBUG --- [ost-startStop-1] o.s.security.web.FilterChainProxy        : Initializing filter 'filterChainProxy'
2017-05-07 20:19:00.613 DEBUG --- [ost-startStop-1] o.s.security.web.FilterChainProxy        : Filter 'filterChainProxy' configured successfully
2017-05-07 20:19:00.613 DEBUG --- [ost-startStop-1] g.p.s.rest.RestLogoutFilter              : Initializing filter 'restLogoutFilter'
2017-05-07 20:19:00.613 DEBUG --- [ost-startStop-1] g.p.s.rest.RestLogoutFilter              : Filter 'restLogoutFilter' configured successfully
2017-05-07 20:19:00.613 DEBUG --- [ost-startStop-1] g.p.s.rest.RestAuthenticationFilter      : Initializing filter 'restAuthenticationFilter'
2017-05-07 20:19:00.613 DEBUG --- [ost-startStop-1] g.p.s.rest.RestAuthenticationFilter      : Filter 'restAuthenticationFilter' configured successfully
2017-05-07 20:19:02.731 DEBUG --- [           main] o.s.s.a.h.RoleHierarchyImpl              : setHierarchy() - The following role hierarchy was set: 
2017-05-07 20:19:03.064 ERROR --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

A component required a bean named '' that could not be found.


Action:

Consider defining a bean named '' in your configuration.

这是我的 application.yml 内容:

---
grails:
    profile: rest-api
    codegen:
        defaultPackage: ras
    spring:
        transactionManagement:
            proxies: false
info:
    app:
        name: '@info.app.name@'
        version: '@info.app.version@'
        grailsVersion: '@info.app.grailsVersion@'
spring:
    main:
        banner-mode: "off"
    groovy:
        template:
            check-template-location: false

# Spring Actuator Endpoints are Disabled by Default
endpoints:
    enabled: false
    jmx:
        enabled: true

---
grails:
    mime:
        disable:
            accept:
                header:
                    userAgents:
                        - Gecko
                        - WebKit
                        - Presto
                        - Trident
        types:
            json:
              - application/json
              - text/json
            hal:
              - application/hal+json
              - application/hal+xml
            xml:
              - text/xml
              - application/xml
            atom: application/atom+xml
            css: text/css
            csv: text/csv
            js: text/javascript
            rss: application/rss+xml
            text: text/plain
            all: '*/*'
    urlmapping:
        cache:
            maxsize: 1000
    controllers:
        defaultScope: singleton
    converters:
        encoding: UTF-8

---
hibernate:
    cache:
        queries: false
        use_second_level_cache: true
        use_query_cache: false
        region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory

dataSource:
    pooled: true
    jmxExport: true
    driverClassName: com.mysql.jdbc.Driver
    dialect: org.hibernate.dialect.MySQL5InnoDBDialect
    username: *******
    password: *******

environments:
    development:
        dataSource:
            dbCreate: create-drop
            url: jdbc:mysql://localhost:3306/ras_dev?autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8&useSSL=false
    test:
        dataSource:
            dbCreate: create-drop
            url: jdbc:mysql://localhost:3306/ras_test?autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8&useSSL=false
    production:
        dataSource:
            dbCreate: update
            url: jdbc:mysql://localhost:3306/ras?autoReconnect=true&useUnicode=yes&characterEncoding=UTF-8
            properties:
                jmxEnabled: true
                initialSize: 5
                maxActive: 50
                minIdle: 5
                maxIdle: 25
                maxWait: 10000
                maxAge: 600000
                timeBetweenEvictionRunsMillis: 5000
                minEvictableIdleTimeMillis: 60000
                validationQuery: SELECT 1
                validationQueryTimeout: 3
                validationInterval: 15000
                testOnBorrow: true
                testWhileIdle: true
                testOnReturn: false
                jdbcInterceptors: ConnectionState
                defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED

application.groovy

grails.plugin.springsecurity.useSecurityEventListener = true
grails.plugin.springsecurity.securityConfigType = 'InterceptUrlMap'

grails.plugin.springsecurity.rememberMe.persistent = true

grails.plugin.springsecurity.rest.login.active = true
grails.plugin.springsecurity.rest.login.useJsonCredentials = true
grails.plugin.springsecurity.rest.login.usernamePropertyName = 'username'
grails.plugin.springsecurity.rest.login.passwordPropertyName = 'password'
grails.plugin.springsecurity.rest.login.failureStatusCode = 401
grails.plugin.springsecurity.rest.login.endpointUrl = '/api/login'
grails.plugin.springsecurity.rest.logout.endpointUrl = '/api/logout'

grails.plugin.springsecurity.rest.token.storage.jwt.useEncryptedJwt = true
grails.plugin.springsecurity.rest.token.storage.jwt.privateKeyPath = 'security/private_key.der'
grails.plugin.springsecurity.rest.token.storage.jwt.publicKeyPath = 'security/public_key.der'

grails.plugin.springsecurity.rest.token.rendering.authoritiesPropertyName = 'permissions'
grails.plugin.springsecurity.rest.token.rendering.usernamePropertyName = 'username'

grails.plugin.springsecurity.rest.token.generation.useSecureRandom = true

grails.plugin.springsecurity.rest.token.validation.headerName = 'X-Auth-Token'
grails.plugin.springsecurity.rest.token.validation.useBearerToken = false

grails.plugin.springsecurity.filterChain.chainMap = [
    ['/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter'], // Stateless chain
    ['/data/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter'], // Stateless chain
    ['/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter']   // Traditional chain
]

grails.plugin.springsecurity.interceptUrlMap = [
    [pattern: '/',               access: ['permitAll']],
    [pattern: '/assets/**',      access: ['permitAll']],
    [pattern: '/partials/**',    access: ['permitAll']],
    [pattern: '/**/js/**',       access: ['permitAll']],
    [pattern: '/**/css/**',      access: ['permitAll']],
    [pattern: '/**/images/**',   access: ['permitAll']],
    [pattern: '/**/favicon.ico', access: ['permitAll']],
    [pattern: '/api/login',      access: ['permitAll']],
    [pattern: '/api/logout',     access: ['isFullyAuthenticated()']],
    [pattern: '/api/validate',   access: ['isFullyAuthenticated()']],
    [pattern: '/**',             access: ['isFullyAuthenticated()']]
]

resources.groovy

import ras.bean.DefaultSecurityEventListener
import ras.auth.DefaultJsonPayloadCredentialsExtractor

beans = 
    credentialsExtractor(DefaultJsonPayloadCredentialsExtractor)
    defaultSecurityEventListener(DefaultSecurityEventListener)

grails 版本:

$ grails --version
| Grails Version: 3.2.6
| Groovy Version: 2.4.7
| JVM Version: 1.8.0_121

更新 1

我在 logback.groovy

中添加了以下行
logger("org.springframework.security", DEBUG, ['STDOUT'], false)
logger("grails.plugin.springsecurity", DEBUG, ['STDOUT'], false)
logger("org.pac4j", DEBUG, ['STDOUT'], false)

然而,控制台输出和 stacktrace.log 文件的输出与上面发布的相同

非常感谢有关如何解决此错误的任何建议。

【问题讨论】:

Spring 库通常非常适合为您提供信息丰富的堆栈跟踪。这似乎不是这里的情况。也许您可以降低日志记录级别以获得更好的信息? 【参考方案1】:

最后,我能够解决问题:

问题 1: 我手动创建了 User Role 和 UserRole 类,而不是使用

grails s2-quickstart com.app-name User Role

如here所述

问题 2: 我对 chainMap 过滤器使用了错误的格式。这是对我有用的那个

grails.plugin.springsecurity.filterChain.chainMap = [
    [pattern: '/assets/**',      filters: 'none'],
    [pattern: '/**/js/**',       filters: 'none'],
    [pattern: '/**/css/**',      filters: 'none'],
    [pattern: '/**/images/**',   filters: 'none'],
    [pattern: '/**/favicon.ico', filters: 'none'],
    [pattern: '/api/**',    filters: 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter'], // Stateless chain
    [pattern: '/data/**',   filters: 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter'], // Stateless chain
    [pattern: '/**',        filters: 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter']   // Traditional chain
]

【讨论】:

【参考方案2】:

com.form.application.UserPasswordEncoderListener 中的字段 springSecurityService 需要找不到类型为“grails.plugin.springsecurity.SpringSecurityService”的 bean。

行动:

考虑在你的配置中定义一个“grails.plugin.springsecurity.SpringSecurityService”类型的bean 还是遇到这个问题

【讨论】:

以上是关于一个组件需要一个名为 '' 的 bean,但无法找到的主要内容,如果未能解决你的问题,请参考以下文章

字段存储库需要一个名为“entityManagerFactory”的 bean,但无法找到

Spring Boot - 存储库字段需要一个名为“entityManagerFactory”的 bean,但无法找到

Spring-boot:需要一个找不到的名为“entityManagerFactory”的bean

找不到名为“entityManagerFactory”的bean

Spring Data JPA - 考虑在您的配置中定义一个名为“entityManagerFactory”的bean

Spring如何知道在哪里搜索组件或Bean?