Vernon (Migrated from SEC-2510) said:
It only occurs for 3.2.1, but not 3.2.0. Here is the exception stack during a start-up:
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.a
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
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:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
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 org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
... 23 more
Caused by: org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:42)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.authenticationManager(WebSecurityConfigurerAdapter.java:228)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:168)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:273)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:58)
at com.vernonwu.vsm.config.WebSecurityConfig$$EnhancerByCGLIB$$94ba9b96.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$$e0d2ce43.CGLIB$springSecurityFilterChain$0(<generated>)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$e0d2ce43$$FastClassByCGLIB$$274f7312.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:326)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$e0d2ce43.springSecurityFilterChain(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 24 more
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.a
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
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:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
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 org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
... 23 more
Caused by: org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:42)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.authenticationManager(WebSecurityConfigurerAdapter.java:228)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:168)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:273)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:58)
at com.vernonwu.vsm.config.WebSecurityConfig$$EnhancerByCGLIB$$94ba9b96.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$$e0d2ce43.CGLIB$springSecurityFilterChain$0(<generated>)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$e0d2ce43$$FastClassByCGLIB$$274f7312.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:326)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$e0d2ce43.springSecurityFilterChain(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 24 more
Error listenerStart
Context [] startup failed due to previous errors
The web application [] registered the JDBC driver [org.postgresql.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Failed to check for ThreadLocal references for web application []
java.lang.NullPointerException
at org.apache.catalina.loader.WebappClassLoader.loadedByThisOrChild(WebappClassLoader.java:2584)
at org.apache.catalina.loader.WebappClassLoader.checkThreadLocalMapForLeaks(WebappClassLoader.java:2500)
at org.apache.catalina.loader.WebappClassLoader.checkThreadLocalsForLeaks(WebappClassLoader.java:2455)
at org.apache.catalina.loader.WebappClassLoader.clearReferences(WebappClassLoader.java:1996)
at org.apache.catalina.loader.WebappClassLoader.stop(WebappClassLoader.java:1902)
at org.apache.catalina.loader.WebappLoader.stopInternal(WebappLoader.java:662)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5669)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
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:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Started Tomcat Server
The Server is running at http://localhost:8080
Rob Winch said:
Please provide the configuration you are using to reproduce this
Vernon said:
My configuration is based on this guide https://spring.io/guides/tutorials/web/6/.
@Order(1)
public class SecurityWebAppInitializer
extends AbstractSecurityWebApplicationInitializer { }
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/home", "greeting").permitAll()
.anyRequest().authenticated();
http.formLogin()
.defaultSuccessUrl("/afterLogin")
.loginPage("/profiles/lognin/form")
.failureUrl("/accessDenied")
.and()
.authorizeRequests()
.regexMatchers("....")
.hasRole("ROLE_USER")
.antMatchers("...")
.hasRole("ROLE_USER")
.regexMatchers("...")
.hasRole("ROLE_OWNER")
.antMatchers("...")
.hasRole("ROLE_OWNER")
.regexMatchers("...")
.hasRole("ROLE_ADMIN")
.antMatchers("..").hasRole("ROLE_ADMIN");
}
@Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder)
throws Exception {
authManagerBuilder.authenticationProvider(this.getDaoAuthenticationProvider()).build();
}
@Bean
public AuthenticationManager authMgr() {
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>();
providers.add(this.getDaoAuthenticationProvider());
return new ProviderManager(providers);
}
private DaoAuthenticationProvider getDaoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider
.setUserDetailsService(getUserDetailsService());
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return daoAuthenticationProvider;
}
private UserDetailsService getUserDetailsService() {
return new UserDetailsServiceImpl();
}
}
Rob Winch said:
The problem is with your configuration. There are multiple issues that I see:
.build() in configure(AuthenticationManagerBuilder authManagerBuilder) This is the root of this error you are getting.hasRole("ROLE_ADMIN"), hasRole("ROLE_OWNER"), etc The ROLE_ should be removed as it is implied when you use hasRole method. For example, hasRole("ADMIN")<intercept-url> each entry under authorizedRequests() is considered in order. So you cannot state .anyRequest().authenticated() and then invoke any other matchers i.e. .regexMatchers("....").hasRole("ROLE_USER") You should instead ensure that anyRequest() is the last method invoked on authorizedRequests()A summary of these changes (there are some more improvements further down), along with some formatting improvement, can be seen below. You can also find a lot of this documented in the reference http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/ and in the guides http://docs.spring.io/spring-security/site/docs/3.2.x/guides/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "greeting").permitAll()
.regexMatchers("....").hasRole("USER") // no ROLE_
.antMatchers("...").hasRole("USER")
.regexMatchers("...").hasRole("OWNER")
.antMatchers("...").hasRole("OWNER")
.regexMatchers("...").hasRole("ADMIN")
.antMatchers("..").hasRole("ADMIN")
.anyRequest().authenticated() // last method on authorizedRequests()
.and()
.formLogin()
.defaultSuccessUrl("/afterLogin")
.loginPage("/profiles/lognin/form")
.failureUrl("/accessDenied");
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth
.authenticationProvider(this.getDaoAuthenticationProvider());
}
@Bean
public AuthenticationManager authMgr() {
List<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>();
providers.add(this.getDaoAuthenticationProvider());
return new ProviderManager(providers);
}
private DaoAuthenticationProvider getDaoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider
.setUserDetailsService(getUserDetailsService());
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return daoAuthenticationProvider;
}
private UserDetailsService getUserDetailsService() {
return new UserDetailsServiceImpl();
}
}
There are a number of things you can do to clean this up:
@EnableWebMvcSecurity instead of @EnableWebSecurity to ensure you have integration with Spring MVC See http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#mvc@Autowired and will be visible everywhere (i.e. method security and http security can see it).@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "greeting").permitAll()
.regexMatchers("....").hasRole("USER")
.antMatchers("...").hasRole("USER")
.regexMatchers("...").hasRole("OWNER")
.antMatchers("...").hasRole("OWNER")
.regexMatchers("...").hasRole("ADMIN")
.antMatchers("..").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/afterLogin")
.loginPage("/profiles/lognin/form")
.failureUrl("/accessDenied")
.permitAll() // grant access to login stuff
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth
.userDetailsService(userDetailsService())
.passwordEncoder(new BCryptPasswordEncoder());
}
@Bean
public UserDetailsServiceImpl userDetailsService() {
return new UserDetailsServiceImpl();
}
}
Also not fighting the defaults will remove some additional configuration. I'd recommend going with the following which is much more concise:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "greeting").permitAll()
.regexMatchers("....").hasRole("USER")
.antMatchers("...").hasRole("USER")
.regexMatchers("...").hasRole("OWNER")
.antMatchers("...").hasRole("OWNER")
.regexMatchers("...").hasRole("ADMIN")
.antMatchers("..").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService())
.passwordEncoder(new BCryptPasswordEncoder());
}
@Bean
public UserDetailsServiceImpl userDetailsService() {
return new UserDetailsServiceImpl();
}
}
I'd encourage you to go over the previously mentioned documentation provided with Spring Security. I'd also look at the existing sample applications http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#jc
Rob Winch said:
As this is a configuration error, this is being marked as invalid
Vernon said:
The configuration works find so far. I run into a log in problem if I don't use the default login form. With a custom login form, I get the following error after clicking the submit button.
HTTP Status 405 - Request method 'POST' not supported
type Status report
message Request method 'POST' not supported
description The specified HTTP method is not allowed for the requested resource.
I can't see any different between the html code of the default one and my custom one. Here is my login form (from the source on a browser generated by Thymeleaf):
form class="form-horizontal" role="form" method="POST" action="/login">
<div class="form-group">
<label for="j_username" class="col-sm-2 control-label">username</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="username" id="username" placeholder="Username" autofocus="autofocus" />
</div>
</div>
<div class="form-group">
<label for="j_password" class="col-sm-2 control-label">password</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password" placeholder="Password" id="password" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label for="rememberMe">
<input type="checkbox" name="_spring_security_remember_me">rememberme</input>
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">submit</button>
</div>
</div>
<div class="form-group">
<a href="/profiles/usernameRetrieval">forgetYourUsernameOrPassword</a>
</div>
<input type="hidden" name="_csrf" value="120af6e9-da06-43b7-81a0-ea85cac3f5e0" />
</form>
Rob Winch said:
It appears you are submitting the incorrect URL, so Spring Security is ignoring it & your application is ignoring it. With your current configuration you should POST to loginPage("/profiles/lognin/form") You can also specify loginProcessingUrl if you would like to change it.
Vernon said:
I see and that works. So, the way of login form configuration isn't the same as the previous version of SS.
Rob Winch said:
Java Configuration was first finalized in Spring Security 3.2.0 so it has always been this way (unless you count the milestones leading up to it which non-passive changes were made). If you mean is it the same as XML, no it is not. Java Configuration tries to have better defaults that XML cannot make due to passivity concerns. In Spring Security 4.0 XML will be updated to have these defaults too.
Vernon said:
I also run into a backward incompatible problem on the logout mechanism. For those non-backward compatible items, the document should have a section of migration notices from a previous version to the 3.2 version. Just a suggestion.
Most helpful comment
Rob Winch said:
The problem is with your configuration. There are multiple issues that I see:
.build()inconfigure(AuthenticationManagerBuilder authManagerBuilder)This is the root of this error you are getting.hasRole("ROLE_ADMIN"),hasRole("ROLE_OWNER"), etc TheROLE_should be removed as it is implied when you usehasRolemethod. For example,hasRole("ADMIN")<intercept-url>each entry underauthorizedRequests()is considered in order. So you cannot state.anyRequest().authenticated()and then invoke any other matchers i.e..regexMatchers("....").hasRole("ROLE_USER")You should instead ensure thatanyRequest()is the last method invoked onauthorizedRequests()A summary of these changes (there are some more improvements further down), along with some formatting improvement, can be seen below. You can also find a lot of this documented in the reference http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/ and in the guides http://docs.spring.io/spring-security/site/docs/3.2.x/guides/
There are a number of things you can do to clean this up:
@EnableWebMvcSecurityinstead of@EnableWebSecurityto ensure you have integration with Spring MVC See http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#mvc@Autowiredand will be visible everywhere (i.e. method security and http security can see it).Also not fighting the defaults will remove some additional configuration. I'd recommend going with the following which is much more concise:
I'd encourage you to go over the previously mentioned documentation provided with Spring Security. I'd also look at the existing sample applications http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#jc