Spring Security:创建 bean 时出错/未定义 bean

Posted

技术标签:

【中文标题】Spring Security:创建 bean 时出错/未定义 bean【英文标题】:Spring Security: Error creating bean/No bean is defined 【发布时间】:2016-03-18 00:26:01 【问题描述】:

我尝试使用 Spring Security 编写一个简单的 Spring 应用程序,但我遇到了错误。这是我收到的例外情况:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'org.springframework.security.filterChains': 
  Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0'
  while setting bean property 'sourceList' with key [0]; 
nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': 
  Cannot resolve reference to bean 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0' 
  while setting constructor argument with key [5]; 
nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': 
  Cannot resolve reference to bean 'org.springframework.security.authentication.ProviderManager#0' 
  while setting bean property 'authenticationManager';
nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'org.springframework.security.authentication.ProviderManager#0': 
  Cannot resolve reference to bean 'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0' 
  while setting constructor argument; 
nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0': 
FactoryBean threw exception on object creation; 
nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'org.springframework.security.authenticationManager': 
  Cannot resolve reference to bean 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0' 
  while setting constructor argument with key [0]; 
nested exception is org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0': 
  Cannot resolve reference to bean 'UserDao' 
  while setting bean property 'userDetailsService'; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No bean named 'UserDao' is defined

我可以看到,bean UserDao 有问题,这是不可见的,尽管我有:<context:component-scan base-package="service, controller, dao" />

我的其余配置:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mycompany</groupId>
    <artifactId>MyLibrary</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>MyLibrary</name>

    <properties>
        <endorsed.dir>$project.build.directory/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>4.3.1.Final</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>4.0.1.RELEASE</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>$endorsed.dir</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>$endorsed.dir</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Spring Security -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-security.xml</param-value>
    </context-param>

    <filter>  
        <filter-name>springSecurityFilterChain</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
    </filter>  

    <filter-mapping>  
        <filter-name>springSecurityFilterChain</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>
</web-app>

调度程序-servlet.xml

<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?xml version="1.0" encoding="UTF-8"?> -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />


    <context:component-scan base-package="service, controller, dao" />


    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
        <property name="persistenceUnitName" value="LibraryPU" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaDialect" ref="jpaDialect" />
    </bean>
    <bean id="jpaVendorAdapter"
          class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="database" value="HSQL" />
        <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
    </bean>

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver" />
        <property name="url" value="jdbc:derby://localhost:1527/Library" />
        <property name="username" value="app" />
        <property name="password" value="app" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

和 spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-4.0.xsd">

    <http auto-config="true">

        <intercept-url pattern="/index" access="hasRole('ROLE_USER')" />

        <access-denied-handler error-page="/login" />

        <form-login 
            login-page="/login" 
            default-target-url="/login" 
            authentication-failure-url="/login?error" 
            username-parameter="username"
            password-parameter="password" />
        <logout logout-success-url="/login?logout"  />
        <csrf/>
    </http>

    <authentication-manager>
            <authentication-provider user-service-ref="UserDao" />
    </authentication-manager>

</beans:beans>

我做错了,所以请帮助我。谢谢!

【问题讨论】:

【参考方案1】:

我觉得你的问题是什么:

 <authentication-manager>
      <authentication-provider user-service-ref="UserDao" />
 </authentication-manager>

我尝试在任何 Spring 项目中找到 UserDao,但我仅在 sample (sample.dao.UserDAO) 中找到。你真的知道 UserDao 类是任何 Spring 框架的一部分吗?据我所知,您需要自己创建 authentication-provider 类。

【讨论】:

UserDao 是我自己的类,它实现了UserDetailsService 接口。 但是为什么你没有在xml中添加这个类,例如 ?请参阅示例中的示例:github.com/spring-projects/spring-security/blob/… 我在dispatcher-servlet.xml 中有&lt;context:component-scan base-package="service, controller, dao" /&gt;,它正在扫描UserDao 包。不一样吗? 我应该把这个bean定义放在哪里? dispatcher-servlet.xmlspring-security.xml? 尝试在spring-security.xml中添加

以上是关于Spring Security:创建 bean 时出错/未定义 bean的主要内容,如果未能解决你的问题,请参考以下文章

创建名为 AuthenticationManager 的 bean 时出错

Spring security-org.springframework.beans.factory.BeanCreationException:创建名为“org.springframework.sec

如何使用 Spring Security 3.1.3 和 JSF 创建一个 Bean 来验证我的登录表单

使用 Spring Security 时,在 bean 中获取当前用户名(即 SecurityContext)信息的正确方法是啥?

使用 Spring Security 时,在 bean 中获取当前用户名(即 SecurityContext)信息的正确方法是啥?

Spring security DefaultMethodSecurityExpressionHandler bean 未注册 Integration Test 的默认 spring security