Application startup failed after adding spring security [duplicate] - java

I want to use #Secured annotations for my controller actions. Since I have java based configuration I need to know how I can set the
<security:global-method-security secured-annotations="enabled" />
option without the xml file.
Upate 1:
I addeed #EnableGlobalMethodSecurity(securedEnabled = true) to my security config class:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class LIRSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authenticationProvider(preAuthenticatedAuthenticationProvider())
.addFilter(cookiePreAuthenticationFilter())
.authorizeRequests()
.antMatchers("/**")
.hasAnyAuthority("ROLE_USER")
;
}
...
}
Up on start-up this causes this exception
Jul 21, 2014 3:32:54 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: 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 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: An AuthenticationManager is required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:633)
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:410)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
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$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Caused by: java.lang.IllegalArgumentException: An AuthenticationManager is required
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:121)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
... 22 more
Jul 21, 2014 3:32:54 PM org.apache.catalina.core.StandardContext
Update 2:
After adding
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
I get an other exception:
Caused by: org.springframework.beans.FatalBeanException: A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication.
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.validateBeanCycle(WebSecurityConfigurerAdapter.java:462)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.<init>(WebSecurityConfigurerAdapter.java:430)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.authenticationManagerBean(WebSecurityConfigurerAdapter.java:220)
at com.galexis.lir.config.LIRSecurityConfig.authenticationManagerBean(LIRSecurityConfig.java:36)
at com.galexis.lir.config.LIRSecurityConfig$$EnhancerBySpringCGLIB$$88306f96.CGLIB$authenticationManagerBean$3(<generated>)
at com.galexis.lir.config.LIRSecurityConfig$$EnhancerBySpringCGLIB$$88306f96$$FastClassBySpringCGLIB$$a4d1ea33.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:293)
at com.galexis.lir.config.LIRSecurityConfig$$EnhancerBySpringCGLIB$$88306f96.authenticationManagerBean(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
... 77 more

You need to use the
#EnableGlobalMethodSecurity(securedEnabled = true)
annotation, as defined in the docs.

You should add also a bean for Manager. Check this out:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Resource(name = "authService")
private UserDetailsService userDetailsService;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
Md5PasswordEncoder encoder = new Md5PasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.and()
.logout()
.logoutSuccessUrl("/");
}
}
Important thing is
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

Just for the others which will try to solve "A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication." problem.
The solution is to add the follwing method:
#Override
#Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// do NOT call super.configure() !
...
}

So this did the work :
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("user").password("user").roles("USER").and().
withUser("admin").password("admin").roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
#Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
}
the important parts are
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("user").password("user").roles("USER").and().
withUser("admin").password("admin").roles("USER", "ADMIN");
}

Stefan is right, adding
#EnableGlobalMethodSecurity(securedEnabled = true)
does the trick.
In my particular situation I had to add to get rid of the excptions.
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").authorities("ROLE_USER");
}

Follow the classes within the annotations
#Configuration
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfigProvider extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
#Configuration
#EnableOAuth2Client
#EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
OAuth2ClientContext oauth2ClientContext;
#Override
protected void configure(HttpSecurity http) throws Exception {
//TODO
}
#Override
public void configure(WebSecurity web) throws Exception {
//TODO
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
#EnableGlobalMethodSecurity(prePostEnabled=true)

Related

Error creating bean with name 'springSecurityConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?

I got error in encoding my inMemory User password using BCryptPasswordEncoder
here is my springsecurityconfig file
SpringSecurityConfig class
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(passwordEncoder().encode("password"))
.roles("USER");
}
#Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
How can i properly encode the password without getting bean creation error
You can use a more component-based approach to do that since the WebSecurityConfigurerAdapter has been deprecated in 5.7.0-M2.
#Configuration
#EnableWebSecurity
public class SpringSecurityConfig {
#Bean
public SecurityFilterChain appSecurity(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
return http.build()
}
#Bean
public UserDetailsService userDetailsService(PasswordEncoder encoder) {
User admin = User.withUsername("admin")
.password(encoder.encode("password"))
.roles("USER").build();
return new InMemoryUserDetailsManager(admin);
}
#Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
This way, you have in-memory authentication by providing a InMemoryUserDetailsManager as the implementation of UserDetailsService, and this bean is dependent on the PasswordEncoder.
You can find more detail on the reference docs.

How to enable #Secured annotation in spring application

I'm using sprig security 4.0.4.RELEASE in my Spring 4.2.5.RELEASE application.
I want to implement the role wise security on method level in my application using #Secured annotation
I'm tried to implement this by adding #EnableGlobalMethodSecurity(securedEnabled = true) but some error is occurring.
Here is my SecurityConfiguration Class
package com.application.security;
import com.application.security.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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 org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("customUserDetailsService")
UserDetailsService userDetailsService;
#Autowired
LoginSuccessHandler loginSuccessHandler;
#Autowired
PersistentTokenRepository tokenRepository;
/*#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}*/
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(customDaoAuthenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().invalidSessionUrl("/logout");
http.authorizeRequests()
/*.antMatchers("/").access("hasRole('USER') or hasRole('ADMIN') or hasRole('DBA')")*/
.antMatchers("/registration").permitAll()
.antMatchers("/exclusion").permitAll()
.antMatchers("/landing").permitAll()
.antMatchers("/uploadSingle").permitAll()
.antMatchers("/uploadSingleNoFile").permitAll()
.antMatchers("/loadHtmlTableAjax").permitAll()
.antMatchers("/AllclaimDetails").permitAll()
.antMatchers("/deleteclaim").permitAll()
.antMatchers("/claimComplete").permitAll()
.antMatchers("/exclusionComplete").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.loginProcessingUrl("/login").usernameParameter("username").passwordParameter("password")
.successHandler(loginSuccessHandler)
.failureUrl("/login?error=true")
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.rememberMe().rememberMeParameter("remember-me").tokenRepository(tokenRepository).tokenValiditySeconds(86400)
.and()
.csrf()
.and()
.exceptionHandling().accessDeniedPage("/Access_Denied");
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/logoff");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
#Bean
CustomDaoAuthenticationProvider customDaoAuthenticationProvider() {
CustomDaoAuthenticationProvider customAuthenticationProvider = new CustomDaoAuthenticationProvider();
customAuthenticationProvider.setUserDetailsService(userDetailsService);
customAuthenticationProvider.setPasswordEncoder(passwordEncoder());
return customAuthenticationProvider;
}
#Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
PersistentTokenBasedRememberMeServices tokenBasedservice = new PersistentTokenBasedRememberMeServices(
"remember-me", userDetailsService, tokenRepository);
return tokenBasedservice;
}
#Bean
public AuthenticationTrustResolver getAuthenticationTrustResolver() {
return new AuthenticationTrustResolverImpl();
}
}
When I'm giving #EnableGlobalMethodSecurity(securedEnabled = true) , the application is not getting started. I'm getting the below error.
The problem is from AuthenticationTrustResolver bean
AnnotationConfigWebApplicationContext:546 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfig': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'metaDataSourceAdvisor': Cannot resolve reference to bean 'methodSecurityMetadataSource' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.setAuthenticationTrustResolver(org.springframework.security.authentication.AuthenticationTrustResolver); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setTrustResolver(org.springframework.security.authentication.AuthenticationTrustResolver); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'getAuthenticationTrustResolver': Requested bean is currently in creation: Is there an unresolvable circular reference?
Can somebody tell me the reason?
Please create Initializer class by extending AbstractSecurityWebApplicationInitializer.
Please refer my answer in here.
No bean named 'springSecurityFilterChain' available
I solved this problem by updating my spring security dependency to latest in pom.xml
I changed the version from
<springsecurity.version>4.0.4.RELEASE</springsecurity.version>
to
<springsecurity.version>4.2.3.RELEASE</springsecurity.version>

StackOverflowError in Spring OAuth2 token request

I have problems implementing OAuth2 with Spring...
This is my Configuration related to Security:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public final void configure(final HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/oauth/token").anonymous();
http.authorizeRequests()
.antMatchers("/**").fullyAuthenticated();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Configuration
#EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private IUserService customUserService;
#Bean
public UserDetailsService userDetailsService() {
return customUserService;
}
#Autowired
private IClientOAuth2DetailsService customClientDetailsService;
#Bean
public ClientDetailsService clientDetailsService() throws Exception {
return customClientDetailsService;
}
#Override
public final void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public final void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService());
}
}
}
Like you can see, I made my own implementation of ClientDetailsService:
private ClientDetailsService internalClientDetailsService;
public ClientOAuth2DetailsServiceImpl() throws Exception {
internalClientDetailsService = new InMemoryClientDetailsServiceBuilder().withClient("admin")
.secret("admin")
.authorizedGrantTypes("password")
.authorities("ROLE_CLIENT")
.and()
.build();
}
#Override
public final ClientDetails loadClientByClientId(final String client) throws ClientRegistrationException {
return internalClientDetailsService.loadClientByClientId(client);
}
I'm using Postman extension in Chrome to test the oauth/token request:
When I send my request, it seems that the ClientDetailsService works fine but after return the ClientDetails, I'm always getting this stacktrace:
java.lang.StackOverflowError: null
at java.lang.ReflectiveOperationException.<init>(Unknown Source) ~[na:1.8.0_45]
at java.lang.reflect.InvocationTargetException.<init>(Unknown Source) ~[na:1.8.0_45]
at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_45]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_45]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:201) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at com.sun.proxy.$Proxy67.authenticate(Unknown Source) ~[na:na]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192) ~[spring-security-core-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:436) ~[spring-security-config-3.2.8.RELEASE.jar:3.2.8.RELEASE]
at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_45]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_45]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:201) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at com.sun.proxy.$Proxy67.authenticate(Unknown Source) ~[na:na]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192) ~[spring-security-core-4.0.3.RELEASE.jar:4.0.3.RELEASE]
I don't understand why... What I'm missing?
Thanks!
Solved!
I was missing this method where you have to configure the AuthenticationManager:
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
...
}
Resolved by changing this method authenticationManagerBean
#Bean
#Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
---Fix---
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

How to enable secured-annotations with Java based configuration?

I want to use #Secured annotations for my controller actions. Since I have java based configuration I need to know how I can set the
<security:global-method-security secured-annotations="enabled" />
option without the xml file.
Upate 1:
I addeed #EnableGlobalMethodSecurity(securedEnabled = true) to my security config class:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class LIRSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authenticationProvider(preAuthenticatedAuthenticationProvider())
.addFilter(cookiePreAuthenticationFilter())
.authorizeRequests()
.antMatchers("/**")
.hasAnyAuthority("ROLE_USER")
;
}
...
}
Up on start-up this causes this exception
Jul 21, 2014 3:32:54 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: 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 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: An AuthenticationManager is required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:633)
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:410)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
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$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Caused by: java.lang.IllegalArgumentException: An AuthenticationManager is required
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:121)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
... 22 more
Jul 21, 2014 3:32:54 PM org.apache.catalina.core.StandardContext
Update 2:
After adding
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
I get an other exception:
Caused by: org.springframework.beans.FatalBeanException: A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication.
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.validateBeanCycle(WebSecurityConfigurerAdapter.java:462)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.<init>(WebSecurityConfigurerAdapter.java:430)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.authenticationManagerBean(WebSecurityConfigurerAdapter.java:220)
at com.galexis.lir.config.LIRSecurityConfig.authenticationManagerBean(LIRSecurityConfig.java:36)
at com.galexis.lir.config.LIRSecurityConfig$$EnhancerBySpringCGLIB$$88306f96.CGLIB$authenticationManagerBean$3(<generated>)
at com.galexis.lir.config.LIRSecurityConfig$$EnhancerBySpringCGLIB$$88306f96$$FastClassBySpringCGLIB$$a4d1ea33.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:293)
at com.galexis.lir.config.LIRSecurityConfig$$EnhancerBySpringCGLIB$$88306f96.authenticationManagerBean(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
... 77 more
You need to use the
#EnableGlobalMethodSecurity(securedEnabled = true)
annotation, as defined in the docs.
You should add also a bean for Manager. Check this out:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Resource(name = "authService")
private UserDetailsService userDetailsService;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
Md5PasswordEncoder encoder = new Md5PasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.and()
.logout()
.logoutSuccessUrl("/");
}
}
Important thing is
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
Just for the others which will try to solve "A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication." problem.
The solution is to add the follwing method:
#Override
#Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// do NOT call super.configure() !
...
}
So this did the work :
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("user").password("user").roles("USER").and().
withUser("admin").password("admin").roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
#Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
}
the important parts are
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("user").password("user").roles("USER").and().
withUser("admin").password("admin").roles("USER", "ADMIN");
}
Stefan is right, adding
#EnableGlobalMethodSecurity(securedEnabled = true)
does the trick.
In my particular situation I had to add to get rid of the excptions.
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").authorities("ROLE_USER");
}
Follow the classes within the annotations
#Configuration
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfigProvider extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
#Configuration
#EnableOAuth2Client
#EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
OAuth2ClientContext oauth2ClientContext;
#Override
protected void configure(HttpSecurity http) throws Exception {
//TODO
}
#Override
public void configure(WebSecurity web) throws Exception {
//TODO
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
#EnableGlobalMethodSecurity(prePostEnabled=true)

Spring Security Java NoSuchMethodException: SecurityConfig.<init>()

I am performing the configuration in my project with Spring Security based in Java config.
Only I'm having a problem initializing Spring Security, I'm using SecurityConfig.class class to initialize the appropriate settings, but the problem is that this class has a constructor that demanded a parameter.
I'm basing myself in the documentation:
http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#abstractsecuritywebapplicationinitializer-with-spring-mvc
public class SecurityConfig implements ConfigAttribute {
....
//~ Constructors ==================
public SecurityConfig(String config) {
Assert.hasText(config, "You must provide a configuration attribute");
this.attrib = config;
}
....
}
SecurityApplicationContext.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true)
#ComponentScan(basePackages="com.tiarebalbi.kupo.configuration.security")
public class SecurityApplicationContext extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Autowired
private Environment env;
#Autowired
private KupoUserDetailsService userDetailService;
/**
* #param auth {#link AuthenticationManagerBuilder}
* #throws Exception {#link Exception}
*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.withDefaultSchema()
.and()
.userDetailsService(userDetailService)
.passwordEncoder(new KupoPasswordEncoder());
}
#Override
#Autowired
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**", "/recover-password", "/recover/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/auth-verify")
.defaultSuccessUrl("/dashboard")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.and()
.rememberMe()
.and()
.sessionManagement()
.maximumSessions(this.env.getRequiredProperty("security.session.max", Integer.class))
.expiredUrl("/login?expired");
}
}
Dispatcher Servlet Initializer:
public class DispatcherServletInitializerContext extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { SecurityConfig.class ,GlobalApplicationContext.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebApplicationContext.class, WebSocketApplicationContext.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter("dispatchOptionsRequest", "true");
registration.setAsyncSupported(true);
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
}
ERROR:
java.lang.NoSuchMethodException: org.springframework.security.access.SecurityConfig.<init>()
at java.lang.Class.getConstructor0(Class.java:2810)
at java.lang.Class.getDeclaredConstructor(Class.java:2053)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1069)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1021)
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.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:788)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:434)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:780)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:284)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1322)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:732)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:490)
at org.eclipse.jetty.maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:280)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:118)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:100)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:155)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:118)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:100)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:118)
at org.eclipse.jetty.server.Server.start(Server.java:342)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:100)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
at org.eclipse.jetty.server.Server.doStart(Server.java:290)
at org.eclipse.jetty.maven.plugin.JettyServer.doStart(JettyServer.java:68)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:564)
at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:360)
at org.eclipse.jetty.maven.plugin.JettyRunMojo.execute(JettyRunMojo.java:168)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:106)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:317)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:152)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:555)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
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.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
You trying to register SecurityConfig.class in application context. But as exception message says:
java.lang.NoSuchMethodException: org.springframework.security.access.SecurityConfig.<init>()
When you add any class to your application context, Spring tries to instanciate them using default constructor. That means that there is no default constructor in SecurityConfig.
I also have no idea why do you try to register class in application context that doesn't mark with #Configuration annotation and doesn't have any #Bean annotation inside. If ou refer to:
http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#hello-web-security-java-configuration
you will see that in that tutorial they created class named SecurityConfig.
So I think you should create your own SecurityConfig and import exactly this one instead of org.springframework.security.access.SecurityConfig
I solved the problem by setting the class as a SecurityConfig.class #Bean and adjusting settings AuthenticationManager
/**
* #return {#link SecurityConfig}
*/
#Bean
public SecurityConfig securityConfigBean() {
SecurityConfig config = new SecurityConfig("kupo-security");
return config;
}
/**
*
* #param auth {#link AuthenticationManagerBuilder}
* #throws Exception {#link Exception}
*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProviders().getDaoProvider());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return new ProviderManager(authProviders());
}

Categories