J'ai récemment démarré un projet avec le framework Spring avec l'objectif de le développer sans aucun fichier de configuration XML, uniquement du code Java.
En ce moment, j'ajoute les fichiers suivants à mon projet:
WebAppConfig.Java
@EnableWebMvc
@ComponentScan(value="org.webapp")
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926);
registry.addResourceHandler("/css/**").addResourceLocations("/fonts/").setCachePeriod(31556926);
registry.addResourceHandler("/img/**").addResourceLocations("/image/").setCachePeriod(31556926);
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
SecurityConfig.Java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("kleber").password("123").roles("USER");
}
}
SecurityWebApplicationInitializer.Java
@Order(value=2)
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SecurityConfig.class);
}
}
Dans cet état, lorsque j'exécute l'application (dans Eclipse), le navigateur affiche le formulaire de connexion par défaut de Spring Security, ainsi qu'une erreur 404 après l'envoi de ce formulaire. Si j'essaie d'entrer directement l'url localhost: 8080/spring/index, je peux accéder à la page qui devrait apparaître après le formulaire de connexion.
Si j'ajoute cette classe:
WebAppInitializer.Java
@Order(value=1)
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(WebAppConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(DispatcherConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
En remplacement de web.xml, en suivant les instructions de la documentation officielle, dans ce lien:
Je ne peux même pas accéder à la page de connexion. La même chose se produit si j'ajoute à la classe SecurityConfig la méthode:
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/fonts/**", "/image/**", "/js/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("spring/index").permitAll()
.failureUrl("spring/erro_login").permitAll()
.defaultSuccessUrl("spring/home")
.and()
.logout()
.logoutSuccessUrl("spring/logout")
.permitAll();
}
Quelqu'un peut voir ce qui me manque?
ps .:
Mon contrôleur est ceci:
@Controller
@RequestMapping(value="spring")
public class SpringController {
@RequestMapping(value="index")
public ModelAndView index() {
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
return mav;
}
@RequestMapping(value="home")
public ModelAndView home() {
ModelAndView mav = new ModelAndView();
mav.setViewName("home");
return mav;
}
@RequestMapping(value="erro_login")
public ModelAndView erro_login() {
ModelAndView mav = new ModelAndView();
mav.setViewName("erro_login");
return mav;
}
@RequestMapping(value="erro_nao_autorizado")
public ModelAndView erro_nao_autorizado() {
ModelAndView mav = new ModelAndView();
mav.setViewName("erro_nao_autorizado");
return mav;
}
@RequestMapping(value="logout")
public ModelAndView logout() {
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
return mav;
}
}
METTRE À JOUR
Cette erreur est affichée dans la console d'Eclipse
Mar 29, 2014 1:28:02 PM org.Apache.catalina.core.StandardContext listenerStart
Grave: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
Java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.Java:265)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.Java:112)
at org.Apache.catalina.core.StandardContext.listenerStart(StandardContext.Java:4937)
at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5434)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:150)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1559)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1549)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
at Java.lang.Thread.run(Thread.Java:744)
Après avoir répondu à cette rubrique, j'essaie de supprimer l'un des deux enregistrements en conflit de l'enregistrement de ContextListeners, de SecurityWebApplicationInitializer ou de WebAppInitializer. Dans les deux cas, j'obtiens cette erreur:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws Java.lang.Exception] threw exception; nested exception is Java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:581)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.Java:1025)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.Java:921)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:487)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.Java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.Java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.Java:112)
at org.Apache.catalina.core.StandardContext.listenerStart(StandardContext.Java:4937)
at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5434)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:150)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1559)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1549)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
at Java.lang.Thread.run(Thread.Java:744)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws Java.lang.Exception] threw exception; nested exception is Java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:181)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:570)
... 23 more
Caused by: Java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL
at org.springframework.util.Assert.isTrue(Assert.Java:65)
at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.setDefaultFailureUrl(SimpleUrlAuthenticationFailureHandler.Java:98)
at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.<init>(SimpleUrlAuthenticationFailureHandler.Java:43)
at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.failureUrl(AbstractAuthenticationFilterConfigurer.Java:199)
at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.updateAuthenticationDefaults(AbstractAuthenticationFilterConfigurer.Java:345)
at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.loginPage(AbstractAuthenticationFilterConfigurer.Java:285)
at org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer.loginPage(FormLoginConfigurer.Java:181)
at org.webapp.security.SecurityConfig.configure(SecurityConfig.Java:27)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.Java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.Java:276)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.Java:61)
at org.webapp.security.SecurityConfig$$EnhancerByCGLIB$$f93abbff.init(<generated>)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.Java:369)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.Java:322)
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.Java:39)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.Java:92)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.CGLIB$springSecurityFilterChain$0(<generated>)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4$$FastClassByCGLIB$$eb934d27.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.Java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.Java:286)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.springSecurityFilterChain(<generated>)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:57)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.lang.reflect.Method.invoke(Method.Java:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:160)
... 24 more
Mar 29, 2014 4:18:30 PM org.Apache.catalina.core.StandardContext listenerStart
Grave: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws Java.lang.Exception] threw exception; nested exception is Java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:581)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.Java:1025)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.Java:921)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:487)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.Java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.Java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.Java:112)
at org.Apache.catalina.core.StandardContext.listenerStart(StandardContext.Java:4937)
at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5434)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:150)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1559)
at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1549)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
at Java.lang.Thread.run(Thread.Java:744)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws Java.lang.Exception] threw exception; nested exception is Java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:181)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.Java:570)
... 23 more
Caused by: Java.lang.IllegalArgumentException: 'spring/index?error' is not a valid redirect URL
at org.springframework.util.Assert.isTrue(Assert.Java:65)
at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.setDefaultFailureUrl(SimpleUrlAuthenticationFailureHandler.Java:98)
at org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler.<init>(SimpleUrlAuthenticationFailureHandler.Java:43)
at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.failureUrl(AbstractAuthenticationFilterConfigurer.Java:199)
at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.updateAuthenticationDefaults(AbstractAuthenticationFilterConfigurer.Java:345)
at org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer.loginPage(AbstractAuthenticationFilterConfigurer.Java:285)
at org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer.loginPage(FormLoginConfigurer.Java:181)
at org.webapp.security.SecurityConfig.configure(SecurityConfig.Java:27)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.Java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.Java:276)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.Java:61)
at org.webapp.security.SecurityConfig$$EnhancerByCGLIB$$f93abbff.init(<generated>)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.Java:369)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.Java:322)
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.Java:39)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.Java:92)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.CGLIB$springSecurityFilterChain$0(<generated>)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4$$FastClassByCGLIB$$eb934d27.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.Java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.Java:286)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$93d7a5f4.springSecurityFilterChain(<generated>)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:57)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.lang.reflect.Method.invoke(Method.Java:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.Java:160)
... 24 more
Java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
Dans votre WebAppInitializer
, vous enregistrez une ContextLoaderListener
.
Parce que vous utilisez AbstractSecurityWebApplicationInitializer
avec le constructeur super
qui accepte un Class[]
Crée une nouvelle instance qui instanciera ContextLoaderListener avec les classes spécifiées.
qui enregistre également une ContextLoaderListener
. Notez la classe javadoc
Lorsqu'il est utilisé avec
AbstractSecurityWebApplicationInitializer(Class...)
, it enregistrera également uneContextLoaderListener
. Lorsqu'il est utilisé avecAbstractSecurityWebApplicationInitializer()
, cette classe est généralement utilisé en plus d'une sous-classe deAbstractContextLoaderInitializer
.
Lorsque l’erreur indique, vous ne pouvez pas avoir deux instances ContextLoaderListener
car elles essaieront toutes deux de créer et d’ajouter une ApplicationContext
à la ServletContext
.
Je pense que le problème est que ceci:
.loginPage("spring/index").permitAll()
devrait être ceci:
.loginPage("/spring/index").permitAll() //note the '/' at the beginning of the uri
J'ai eu un cours
MyContextLoaderListener étend ContextLoaderListener
quelque part dans mon code. C'était inutilisé. La botte de printemps a apparemment utilisé la réflexion pour la trouver. J'ai supprimé le fichier et le problème avait disparu
Peut-être existe-t-il un chevauchement conflictuel entre votre web.xml
et le configuration class
basé sur Java. C'est la cause première lorsque j'ai rencontré la même erreur que vous. Et ma solution est de commenter la configuration dupliquée dans web.xml
.