Spring 启动 Jetty 时出现安全错误:没有可用的名为 'org.springframework.web.filter.DelegatingFilterProxy-1b68ddbd' 的 bean

Spring Security Error when starting Jetty: No bean named 'org.springframework.web.filter.DelegatingFilterProxy-1b68ddbd' available

我知道以前有人问过这个问题,但是 none 的建议答案对我有用。 使用 Spring Security 启动 Jetty 时出现此错误:

No bean named 'org.springframework.web.filter.DelegatingFilterProxy-1b68ddbd' available

applicationContext.xml:

<?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:tx="http://www.springframework.org/schema/tx"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/data/jpa
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <context:component-scan base-package="de.pack.webservice" />
    <context:annotation-config />
[...]

    <jpa:repositories base-package="de.pack.webservice.security"
        entity-manager-factory-ref="customEntityManagerFactory" />

</beans>

SecurityConfig.java

package de.pack.webservice.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
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;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;

import de.pack.webservice.security.StandardPasswordEncoder;

@EnableWebSecurity
@Configuration
@Import(PrePostEnabledConfig.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userService;

    @Autowired
    private StandardPasswordEncoder encoder;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userService);
        authProvider.setPasswordEncoder(encoder);
        ReflectionSaltSource saltSource = new ReflectionSaltSource();
        saltSource.setUserPropertyToUse("salt");
        authProvider.setSaltSource(saltSource);
        auth.authenticationProvider(authProvider);
        System.out.println("in gobal");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println("in configure");
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable().authorizeRequests().anyRequest().authenticated()
                .and().httpBasic();
    }
}

对于 Dev,我们不使用 Web.xml,而是在服务器启动时设置参数。这是过滤器定义的相关部分:

        ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
        contextHandler.setContextPath("/");
        contextHandler.setInitParameter("contextConfigLocation", "classpath*:**applicationContext.xml");
        contextHandler.addEventListener(new ResteasyBootstrap());
        contextHandler.addEventListener(new SpringContextLoaderListener());
        ServletHolder holder = new ServletHolder(new HttpServletDispatcher());
        holder.setInitParameter("javax.ws.rs.Application", WebApplication.class.getName());
        contextHandler.addServlet(holder, "/*");

        EnumSet<DispatcherType> x = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE);
        contextHandler.addFilter(DelegatingFilterProxy.class, "/*", x);

        server.setHandler(contextHandler);

如下配置 DelegatingFilterProxy:

context.addFilter(new FilterHolder(new DelegatingFilterProxy("springSecurityFilterChain")), "/*", x);

实际上Spring安全寻找一个名为springSecurityFilterChain的bean(默认情况下),它指向org.springframework.web.filter.DelegatingFilterProxy