Java 小版本更新后的Spring安全异常:“0”;请确保Spring安全和;Spring MVC在共享的ApplicationContext中配置;
在我的Spring框架从到和Spring security 4.2.3到4.2.4进行了一次小升级之后,我的web应用程序无法初始化(Tomcat 8.5.23,JDK 1.8.0_152),错误如下:Java 小版本更新后的Spring安全异常:“0”;请确保Spring安全和;Spring MVC在共享的ApplicationContext中配置;,java,spring,spring-mvc,spring-security,Java,Spring,Spring Mvc,Spring Security,在我的Spring框架从到和Spring security 4.2.3到4.2.4进行了一次小升级之后,我的web应用程序无法初始化(Tomcat 8.5.23,JDK 1.8.0_152),错误如下: [DEBUG] Retrieved dependent beans for bean 'springSecurityFilterChain': [webSecurityExpressionHandler] [WARN] Exception encountered during context i
[DEBUG] Retrieved dependent beans for bean 'springSecurityFilterChain': [webSecurityExpressionHandler]
[WARN] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'springSecurityFilterChain' defined in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mvcHandlerMappingIntrospector' available: A Bean named mvcHandlerMappingIntrospector of type org.springframework.web.servlet.handler.HandlerMappingIntrospector is required to use MvcRequestMatcher.
Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.
引发此异常的类是,它是
spring security
的一部分
我在这个错误()上找到了一个有用的线程,它解释了这个异常是对Spring新版本(5.0.3和4.3.14,它们在同一天)中的无效配置进行额外检查的结果
我的WebConfig
类具有@EnableWebSecurity
注释,如上线程中所述,该注释导入DelegatingWebMvcConfiguration
,该注释声明了
本质上,该线程表明已经声明了多个上下文(根上下文和子上下文),并且我可能在多个上下文中启用了Spring安全性
然而,在我的案例中,我看不到解决方案。我是否有重复/重叠的批注?我是否在WebInitializer
类中错误地加载了根目录和安全配置
下面列出了我的Spring配置类(除了我的AuthenticationProvider
)
WebInitializer.java
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {RootConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class<?>[] {WebConfig.class};
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
package com.x.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"com.x.spring.controller"}, excludeFilters = {@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig
{
}
package com.x.spring;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.x.spring.controller")
public class WebConfig extends WebMvcConfigurerAdapter
{
@Bean
public ViewResolver viewResolver()
{
final TilesViewResolver resolver = new TilesViewResolver();
return resolver;
}
@Bean
public TilesConfigurer tilesConfigurer()
{
final TilesConfigurer tiles = new TilesConfigurer();
tiles.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
tiles.setCheckRefresh(true);
return tiles;
}
@Bean
public CommonsMultipartResolver multipartResolver()
{
final CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10000000);
return resolver;
}
// These methods enable '.' in RequestMappings.
@Override
public final void configurePathMatch(final PathMatchConfigurer configurer)
{
configurer.setUseRegisteredSuffixPatternMatch(true);
return;
}
@Override
public final void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
return;
}
@Override
public void addCorsMappings(final CorsRegistry registry)
{
registry.addMapping("/**");
return;
}
}
package com.x.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.x.spring.security.XAuthenticationProvider;
/**
* Spring web security configuration.
* This class must be registered with WebInitializer.
*/
@Configuration
@EnableWebSecurity
@ComponentScan("com.x.spring.security")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private XAuthenticationProvider authenticationProvider;
/**
* https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/
*/
public WebSecurityConfig()
{
super();
return;
}
@Override
public void configure(final WebSecurity web) throws Exception
{
super.configure(web);
return;
}
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.csrf().disable()
.cors()
.and().headers().frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers("/my-account").hasAuthority("USER")
.anyRequest().permitAll()
.and().httpBasic().realmName("X")
.and().formLogin().loginPage("/login")
.and().logout().logoutSuccessUrl("/")
.and().rememberMe().key("XSecured")
;
return;
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(this.authenticationProvider);
return;
}
}
package com.x.spring;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
* This class is discovered by Spring and registers the DelegatingFilterProxy with the web container.
* It will intercept requests coming into the application and delegate them to a bean whose ID is springSecurityFilterChain.
*/
public final class WebSecurityInitializer extends AbstractSecurityWebApplicationInitializer
{
}
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {WebConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return null;
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
WebConfig.java
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {RootConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class<?>[] {WebConfig.class};
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
package com.x.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"com.x.spring.controller"}, excludeFilters = {@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig
{
}
package com.x.spring;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.x.spring.controller")
public class WebConfig extends WebMvcConfigurerAdapter
{
@Bean
public ViewResolver viewResolver()
{
final TilesViewResolver resolver = new TilesViewResolver();
return resolver;
}
@Bean
public TilesConfigurer tilesConfigurer()
{
final TilesConfigurer tiles = new TilesConfigurer();
tiles.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
tiles.setCheckRefresh(true);
return tiles;
}
@Bean
public CommonsMultipartResolver multipartResolver()
{
final CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10000000);
return resolver;
}
// These methods enable '.' in RequestMappings.
@Override
public final void configurePathMatch(final PathMatchConfigurer configurer)
{
configurer.setUseRegisteredSuffixPatternMatch(true);
return;
}
@Override
public final void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
return;
}
@Override
public void addCorsMappings(final CorsRegistry registry)
{
registry.addMapping("/**");
return;
}
}
package com.x.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.x.spring.security.XAuthenticationProvider;
/**
* Spring web security configuration.
* This class must be registered with WebInitializer.
*/
@Configuration
@EnableWebSecurity
@ComponentScan("com.x.spring.security")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private XAuthenticationProvider authenticationProvider;
/**
* https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/
*/
public WebSecurityConfig()
{
super();
return;
}
@Override
public void configure(final WebSecurity web) throws Exception
{
super.configure(web);
return;
}
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.csrf().disable()
.cors()
.and().headers().frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers("/my-account").hasAuthority("USER")
.anyRequest().permitAll()
.and().httpBasic().realmName("X")
.and().formLogin().loginPage("/login")
.and().logout().logoutSuccessUrl("/")
.and().rememberMe().key("XSecured")
;
return;
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(this.authenticationProvider);
return;
}
}
package com.x.spring;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
* This class is discovered by Spring and registers the DelegatingFilterProxy with the web container.
* It will intercept requests coming into the application and delegate them to a bean whose ID is springSecurityFilterChain.
*/
public final class WebSecurityInitializer extends AbstractSecurityWebApplicationInitializer
{
}
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {WebConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return null;
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
WebSecurityConfig.java
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {RootConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class<?>[] {WebConfig.class};
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
package com.x.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"com.x.spring.controller"}, excludeFilters = {@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig
{
}
package com.x.spring;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.x.spring.controller")
public class WebConfig extends WebMvcConfigurerAdapter
{
@Bean
public ViewResolver viewResolver()
{
final TilesViewResolver resolver = new TilesViewResolver();
return resolver;
}
@Bean
public TilesConfigurer tilesConfigurer()
{
final TilesConfigurer tiles = new TilesConfigurer();
tiles.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
tiles.setCheckRefresh(true);
return tiles;
}
@Bean
public CommonsMultipartResolver multipartResolver()
{
final CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10000000);
return resolver;
}
// These methods enable '.' in RequestMappings.
@Override
public final void configurePathMatch(final PathMatchConfigurer configurer)
{
configurer.setUseRegisteredSuffixPatternMatch(true);
return;
}
@Override
public final void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
return;
}
@Override
public void addCorsMappings(final CorsRegistry registry)
{
registry.addMapping("/**");
return;
}
}
package com.x.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.x.spring.security.XAuthenticationProvider;
/**
* Spring web security configuration.
* This class must be registered with WebInitializer.
*/
@Configuration
@EnableWebSecurity
@ComponentScan("com.x.spring.security")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private XAuthenticationProvider authenticationProvider;
/**
* https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/
*/
public WebSecurityConfig()
{
super();
return;
}
@Override
public void configure(final WebSecurity web) throws Exception
{
super.configure(web);
return;
}
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.csrf().disable()
.cors()
.and().headers().frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers("/my-account").hasAuthority("USER")
.anyRequest().permitAll()
.and().httpBasic().realmName("X")
.and().formLogin().loginPage("/login")
.and().logout().logoutSuccessUrl("/")
.and().rememberMe().key("XSecured")
;
return;
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(this.authenticationProvider);
return;
}
}
package com.x.spring;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
* This class is discovered by Spring and registers the DelegatingFilterProxy with the web container.
* It will intercept requests coming into the application and delegate them to a bean whose ID is springSecurityFilterChain.
*/
public final class WebSecurityInitializer extends AbstractSecurityWebApplicationInitializer
{
}
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {WebConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return null;
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
WebSecurityInitializer.java
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {RootConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class<?>[] {WebConfig.class};
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
package com.x.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"com.x.spring.controller"}, excludeFilters = {@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig
{
}
package com.x.spring;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.x.spring.controller")
public class WebConfig extends WebMvcConfigurerAdapter
{
@Bean
public ViewResolver viewResolver()
{
final TilesViewResolver resolver = new TilesViewResolver();
return resolver;
}
@Bean
public TilesConfigurer tilesConfigurer()
{
final TilesConfigurer tiles = new TilesConfigurer();
tiles.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
tiles.setCheckRefresh(true);
return tiles;
}
@Bean
public CommonsMultipartResolver multipartResolver()
{
final CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10000000);
return resolver;
}
// These methods enable '.' in RequestMappings.
@Override
public final void configurePathMatch(final PathMatchConfigurer configurer)
{
configurer.setUseRegisteredSuffixPatternMatch(true);
return;
}
@Override
public final void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
return;
}
@Override
public void addCorsMappings(final CorsRegistry registry)
{
registry.addMapping("/**");
return;
}
}
package com.x.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.x.spring.security.XAuthenticationProvider;
/**
* Spring web security configuration.
* This class must be registered with WebInitializer.
*/
@Configuration
@EnableWebSecurity
@ComponentScan("com.x.spring.security")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private XAuthenticationProvider authenticationProvider;
/**
* https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/
*/
public WebSecurityConfig()
{
super();
return;
}
@Override
public void configure(final WebSecurity web) throws Exception
{
super.configure(web);
return;
}
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.csrf().disable()
.cors()
.and().headers().frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers("/my-account").hasAuthority("USER")
.anyRequest().permitAll()
.and().httpBasic().realmName("X")
.and().formLogin().loginPage("/login")
.and().logout().logoutSuccessUrl("/")
.and().rememberMe().key("XSecured")
;
return;
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(this.authenticationProvider);
return;
}
}
package com.x.spring;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
* This class is discovered by Spring and registers the DelegatingFilterProxy with the web container.
* It will intercept requests coming into the application and delegate them to a bean whose ID is springSecurityFilterChain.
*/
public final class WebSecurityInitializer extends AbstractSecurityWebApplicationInitializer
{
}
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {WebConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return null;
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
初始化错误是由重复的上下文引起的。具体来说,
RootConfig
类与WebConfig
类是冗余的。通过删除RootConfig
并将WebInitializer.getRootConfigClasses()
更改为返回WebConfig
,而不是RootConfig
和WebInitializer.getServletConfigClasses()
来解决此问题
下面是我的工作WebInitializer
类。除了删除RootConfig
,其他类不需要更改
WebInitializer.java
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {RootConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class<?>[] {WebConfig.class};
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
package com.x.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"com.x.spring.controller"}, excludeFilters = {@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig
{
}
package com.x.spring;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.x.spring.controller")
public class WebConfig extends WebMvcConfigurerAdapter
{
@Bean
public ViewResolver viewResolver()
{
final TilesViewResolver resolver = new TilesViewResolver();
return resolver;
}
@Bean
public TilesConfigurer tilesConfigurer()
{
final TilesConfigurer tiles = new TilesConfigurer();
tiles.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
tiles.setCheckRefresh(true);
return tiles;
}
@Bean
public CommonsMultipartResolver multipartResolver()
{
final CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10000000);
return resolver;
}
// These methods enable '.' in RequestMappings.
@Override
public final void configurePathMatch(final PathMatchConfigurer configurer)
{
configurer.setUseRegisteredSuffixPatternMatch(true);
return;
}
@Override
public final void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
return;
}
@Override
public void addCorsMappings(final CorsRegistry registry)
{
registry.addMapping("/**");
return;
}
}
package com.x.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.x.spring.security.XAuthenticationProvider;
/**
* Spring web security configuration.
* This class must be registered with WebInitializer.
*/
@Configuration
@EnableWebSecurity
@ComponentScan("com.x.spring.security")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private XAuthenticationProvider authenticationProvider;
/**
* https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/
*/
public WebSecurityConfig()
{
super();
return;
}
@Override
public void configure(final WebSecurity web) throws Exception
{
super.configure(web);
return;
}
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.csrf().disable()
.cors()
.and().headers().frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers("/my-account").hasAuthority("USER")
.anyRequest().permitAll()
.and().httpBasic().realmName("X")
.and().formLogin().loginPage("/login")
.and().logout().logoutSuccessUrl("/")
.and().rememberMe().key("XSecured")
;
return;
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(this.authenticationProvider);
return;
}
}
package com.x.spring;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
* This class is discovered by Spring and registers the DelegatingFilterProxy with the web container.
* It will intercept requests coming into the application and delegate them to a bean whose ID is springSecurityFilterChain.
*/
public final class WebSecurityInitializer extends AbstractSecurityWebApplicationInitializer
{
}
package com.x.spring;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public final class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class<?>[] {WebConfig.class, WebSecurityConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return null;
}
@Override
protected String[] getServletMappings()
{
return new String[] {"/"};
}
@Override
protected DispatcherServlet createDispatcherServlet(final WebApplicationContext servletAppContext)
{
final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
package com.x.spring;
导入org.springframework.web.context.WebApplicationContext;
导入org.springframework.web.servlet.DispatcherServlet;
导入org.springframework.web.servlet.support.AbstractAnnotationConfigDispatchersServletInitializer;
公共最终类WebInitializer扩展了AbstractAnnotationConfigDispatcherServletInitializer
{
@凌驾
受保护类[]getRootConfigClasses()
{
返回新类[]{WebConfig.Class,WebSecurityConfig.Class};
}
@凌驾
受保护类[]getServletConfigClasses()
{
返回null;
}
@凌驾
受保护的字符串[]getServletMappings()
{
返回新字符串[]{”/“};
}
@凌驾
受保护的DispatcherServlet createDispatcherServlet(最终WebApplicationContext servletAppContext)
{
最终DispatcherServlet DispatcherServlet=(DispatcherServlet)super.createDispatcherServlet(servletAppContext);
dispatcherServlet.SetThroweExceptionIfNoHandlerFound(true);
返回调度服务器;
}