Spring 安全错误:没有名为“springSecurityFilterChain”的 bean 可用

Posted

技术标签:

【中文标题】Spring 安全错误:没有名为“springSecurityFilterChain”的 bean 可用【英文标题】:Spring security error : No bean named 'springSecurityFilterChain' available 【发布时间】:2017-12-16 21:46:24 【问题描述】:

我已经阅读了大部分已经发布的类似问题,但仍然找不到解决方案。尝试运行我的应用程序时出现错误 No bean named 'springSecurityFilterChain' available。我在我的 pom.xml 文件中导入了 spring 安全依赖项,我在我的 SecurityConfig 类中注释了 @EnableWebSecurity 但仍然无法工作我找不到问题。

pom.xml

<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.example</groupId>
    <artifactId>app</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>app</name>
    <packaging>war</packaging>
    <description>       </description>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.11.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>3.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.42</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.2.10.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>4.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>4.2.3.RELEASE</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>4.2.3.RELEASE</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>4.2.3.RELEASE</version>
        </dependency>



    </dependencies>

</project>

安全配置类

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;



@Configuration
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter


    @Autowired
    private DataSource dataSource;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
        auth
          .jdbcAuthentication()
            .dataSource(dataSource);
            //.passwordEncoder(bcryptEncoder); 
    

    protected void configure(HttpSecurity http) throws Exception 
        http
            .authorizeRequests()
            .antMatchers("/login").permitAll()
            .antMatchers("/admin").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
            .formLogin()
                  .loginPage("/login")
                .and()
            .httpBasic();
      

SecurityWebApplicationInitializer 类

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer


【问题讨论】:

SecurityConfigSecurityWebApplicationInitializer在同一个包中? @JimHawkins 是的 你在其他 Spring 相关的类中使用了哪些注解?请将这些信息添加到您的问题中 ***.com/questions/28616569/… 我希望上一篇文章有​​所帮助。没有堆栈跟踪,很难弄清楚发生了什么 【参考方案1】:

我认为您没有将安全配置导入 Spring 根上下文。

在我的应用程序中,我有一个 AbstractAnnotationConfigDispatcherServletInitializer 的实现,其中方法 getRootConfigClasses 返回 Spring 根配置类(我只有一个):

import javax.servlet.*;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException
     super.onStartup(servletContext); 

    @Override
    protected Class<?>[] getRootConfigClasses()
     return new Class[]MyRoot.class;

    @Override
    protected Class<?>[] getServletConfigClasses()
     return null; 

    @Override
    protected String[] getServletMappings()
     return new String[]"/"; 

    @Override
    protected String getServletName()
     return "myDispatcherServlet"; 

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration)
    
        super.customizeRegistration(registration);
        registration.setLoadOnStartup(1);
    

MyRoot 包含我的 Spring Bean。看注解@Import

@Configuration
@PropertySource("file:$my.config")
@ComponentScan(basePackages = 
        "com.my.filter", "com.my.controller"
        , "com.my.registration"
)

@EnableTransactionManagement(mode = AdviceMode.PROXY, proxyTargetClass = false)
@Import(MySecurityConfigurer.class, MyWebConfigurer.class)
public class DmRoot

    private final Environment env;

    @Autowired
    public MyRoot(Environment env)
    
        Assert.notNull(env, "die Umgebungseinstellungen sind NULL");
        this.env = env;
        dbUserModelPackage = env.getProperty("my.userDbModel");
        dbAccountingModelPackage = env.getProperty("my.accountingDbModel");
    

   // all my Spring beans

看看@Import(MySecurityConfigurer.class, MyWebConfigurer.class)MySecurityConfigurer是我对org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter的扩展,MyWebConfigurer是我对org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter的扩展

@EnableWebMvc
@EnableWebSecurity
public class MySecurityConfigurer extends WebSecurityConfigurerAdapter

    private final Environment env;
    private final UserDetailsService myUserDetailsService;

    @Autowired
    public MySecurityConfigurer(Environment env, UserDetailsService myUserDetailsService)
    
        Assert.notNull(env, "die Umgebungseinstellungen sind NULL");
        this.env = env;
        Assert.notNull(myUserDetailsService, "der myUserDetailsService ist NULL");
        this.myUserDetailsService = myUserDetailsService;
    

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    
        String urlPattern = env.getProperty("my.springSecurityPattern");
        String realmName = env.getProperty("my.springSecurityRealm");
        String reloadPairingUrl = env.getProperty("my.reloadPairingUrl");

        HttpSecurity securityAdapter = httpSecurity.httpBasic().realmName(realmName)
                .and().userDetailsService(myUserDetailsService)
                .authorizeRequests()
                .antMatchers(reloadPairingUrl).permitAll()
                .antMatchers(urlPattern).authenticated()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().csrf().disable();
    


此代码不用于具有用户会话的 Web UI,而是用于通过 HTTPS 进行基本身份验证的服务

【讨论】:

我没有把它放在@ComponentScan(basePackages = ) 中,它为什么无法识别它。当我完成它时,它起作用了! :)【参考方案2】:

确保 security.xml 由 ContextLoaderListener 而不是 DispatcherServlet 加载。 DelegatingFilterProxy 只会查看根应用程序上下文(由 ContextLoaderListener 加载)以供 bean 委托。

例如:

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

【讨论】:

以上是关于Spring 安全错误:没有名为“springSecurityFilterChain”的 bean 可用的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot中开启Spring Security

Grails - SSL 和 Spring 安全核心

春季安全单点登录浏览器

Spring Security入门(2-2)Spring Security 的运行原理 2

在 Spring Boot 安全性中,无法跳过登录 url 的 OncePerRequestFilter 过滤器(基本上是在初始登录期间获取 JWT 令牌)

没有名为“mongoTemplate”的 bean 可用。 Spring Boot + MongoDB