Spring Security: Not able to configure method security with java config
java, spring, spring-java-config, spring-mvc, spring-security
Solution
It sounds as though you are encountering an ordering issue as described in SEC-2477.
As a workaround, you can should be able to use the configure method with the authenticationManagerBean method. Do not use the @Autowired AuthenticationManagerBuilder approach.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
ShaPasswordEncoder shaPasswordEncoder = new ShaPasswordEncoder(256);
auth
.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery(getUserQuery())
.authoritiesByUsernameQuery(getAuthoritiesQuery())
.passwordEncoder(shaPasswordEncoder);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
Problem
I am struggling to configure method security with java configured spring security. My configuration works without any problem, until I use the @Secured annotation within any controller. Spring Security Config: (java config) ``` @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled=true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private DataSource dataSource; @Override public void configure(WebSecurity web) throws Exception { web .ignoring() .antMatchers("/webjars/**","/css/**", "/less/**","/img/**","/js/**"); } @Autowired public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception { ShaPasswordEncoder shaPasswordEncoder = new ShaPasswordEncoder(256); auth .jdbcAuthentication() .dataSource(dataSource) .usersByUsernameQuery(getUserQuery()) .authoritiesByUsernameQuery(getAuthoritiesQuery()) .passwordEncoder(shaPasswordEncoder); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().hasAuthority("BASIC_PERMISSION") .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/success-login", true) .failureUrl("/error-login") .loginProcessingUrl("/process-login") .usernameParameter("security_username") .passwordParameter("security_password") .permitAll() .and() .logout() .logoutSuccessUrl("/login") .logoutUrl("/logout") .permitAll() .and() .rememberMe() .key("04E87501B3F04DB297ADB74FA8BD48CA") .and() .csrf() .disable(); } private String getUserQuery() { return "SELECT username as username, password as password, active as enabled " + "FROM employee " + "WHERE username = ?"; } private String getAuthoritiesQuery() { return "SELECT DISTINCT employee.username as username, permission.name as authority " + "FROM employee, employee_role, role, role_permission, permission " + "WHERE employee.id = employee_role.employee_id " + "AND role.id = employee_role.role_id " + "AND role.id = role_permission.role_id " + "AND permission.id = role_permission.permission_id " + "AND employee.username = ? " + "AND employee.active = 1"; } } ``` As soon as I add the `@Secured("EMPLOYEE_DELETE")` Annotation to any controller method,I receive following exception. ``` java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found [] ``` So I added an `AuthenticationManager` bean: ``` @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } ``` But this has another error as result: ``` java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.provisioning.JdbcUserDetailsManagerConfigurer@34e81675 to already built object ``` It seems that I have to share the `authenticationManagerBean` with the configured `jdbcAuthentication` but I am not able to do this. Thanks for your help in advance!