Spring: Enable global method security in Controller layer by java config
java, spring, spring-java-config, spring-mvc, spring-security
Solution
Update (after updated question)
It appears you are encountering SEC-2479. There are a few ways around this. The easiest of which is to use the result of @Autowired for the AuthenticationManager. To do this you must extend GlobalMethodSecurityConfiguration and override the authenticationManager method.
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
private AuthenticationManager am;
@Override
protected AuthenticationManager authenticationManager() {
return am;
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
// ... create and return custom MethodSecurityExpressionHandler ...
return expressionHander;
}
}
Original Answer
You need to configure some sort of Authentication. So you will need to have the following:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
If you are not using web based security, the reference provides an example of how to configure the method security expression handler.
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
// ... create and return custom MethodSecurityExpressionHandler ...
return expressionHander;
}
}
If you are only wanting a custom method expression handler to provide a permission evaluator, then you only need to create a PermissionEvaluator bean like this:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Bean
public PermissionEvaluator permissionEvaluator() {
// ... create and return custom PermissionEvaluator ...
return permissionEvaluator;
}
}
Problem
I'm trying to migrate my xml servlet config to java config. The below config is my servlet configuration, that enables custom security annotations on Controller layer. ``` <security:global-method-security pre-post-annotations="enabled"> <security:expression-handler ref="expressionHandler"/> </security:global-method-security> <bean id="expressionHandler" class="yyy.MyMethodSecurityExpressionHandler" /> ``` I've also have a working spring security xml configuration, that is in order to be replaced by java config, but not now. Here some pieces of my security config: ``` <bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="userDetailsService" /> </bean> <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager"> <constructor-arg> <ref bean="authenticationProvider"/> </constructor-arg> </bean> <security:authentication-manager> <security:authentication-provider user-service-ref="userDetailsService" /> </security:authentication-manager> <security:global-method-security pre-post-annotations="enabled" /> ``` I want to start to migrate my servlet config enabling security `@PreAuthorize` and `@PostAuthorize` tag in Controller layer. I've found this annotation: `@EnableGlobalMethodSecurity(prePostEnabled=true)`, but putting it on my servlet config: ``` @Configuration @ComponentScan(basePackages= { "....." }) @EnableGlobalMethodSecurity(prePostEnabled=true) public class WebappServletConfig extends WebMvcConfigurationSupport { ``` I get this exception: ``` java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [] ``` Moreover I don't know how to set my custom expression-handler! someone with some tips? Thank you