Rogelio Blanco
Rogelio Blanco

Reputation: 1671

Spring Boot + Security + Multi HTTP Web Configuration

I'm trying to do an example using spring-boot with spring security. My idea is to create a web app and also provide an API, I would like to both have security; so I need to create a multi http web security configuration however it is not working.

I followed this link http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity but no success. And, I'm getting this error

Error creating bean with name 'webSecurityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer to already built object

The configuration that I'm using is the following:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalAuthentication
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfiguration { 

@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth
        .inMemoryAuthentication()
            .withUser("user").password("12345").roles("USER").and()
            .withUser("admin").password("12345").roles("USER", "ADMIN");
}

@Configuration
@Order(1)
public static class ApiConfigurationAdapter extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/api/**")
            .authorizeRequests()
                .anyRequest().hasRole("ADMIN")
                .and()
            .httpBasic();
    }
}

@Configuration
@Order(2)
public static class WebConfigurationAdapter extends
        WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .ignoring()
                .antMatchers("/resources/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()                    
                .antMatchers("/", "/home").permitAll()
            .anyRequest()
                .authenticated()
            .and()
                .formLogin()
                    .loginPage("/login").permitAll()
            .and()
                .logout().permitAll();
    }
    }
}

Thanks in advance

Upvotes: 8

Views: 12487

Answers (3)

Rogelio Blanco
Rogelio Blanco

Reputation: 1671

after a lot of reading I found something that works for me:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {

    @Resource(name = "customUserDetailsService")
    protected CustomUserDetailsService customUserDetailsService;

    @Resource
    private DataSource dataSource;

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService);
    }

    @Configuration
    @Order(1)
    public static class ApiConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Resource(name = "restUnauthorizedEntryPoint")
        private RestUnauthorizedEntryPoint restUnauthorizedEntryPoint;
        @Resource(name = "restAccessDeniedHandler")
        private RestAccessDeniedHandler restAccessDeniedHandler;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> securityXAuthConfigurerAdapter = new XAuthTokenConfigurer(
                    userDetailsServiceBean());

            // @formatter:off
            http
                .antMatcher("/api/**").csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .exceptionHandling()
                    .authenticationEntryPoint(restUnauthorizedEntryPoint)
                    .accessDeniedHandler(restAccessDeniedHandler)
                .and()
                    .authorizeRequests()
                        .antMatchers(HttpMethod.POST, "/api/authenticate").permitAll()
                        .anyRequest().hasRole("ADMIN")
                        .and()
                        .apply(securityXAuthConfigurerAdapter);
            // @formatter:on
        }
    }

    @Configuration
    @Order(2)
    public static class WebConfigurationAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                .authorizeRequests()
                    .antMatchers("/", "/home").permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                        .loginPage("/login").permitAll()
                    .and()
                    .logout().permitAll()
            ;
            // @formatter:on
        }
    }
}

Upvotes: 9

dave
dave

Reputation: 1474

I found I could solve this problem by annotating my class with @EnableWebSecurity after reading this hint: https://github.com/spring-projects/spring-data-examples/issues/189#issuecomment-229552207

Upvotes: 0

Faraj Farook
Faraj Farook

Reputation: 14875

I'm also faced the same issue. But I got it solved when I extend the WebSecurityConfiguration master class from WebSecurityConfigurerAdapter.

Kindly refer the following stackoverflow post in which you can find the full configuration.

Spring Security HTTP Basic for RESTFul and FormLogin for web - Annotations

Upvotes: 0

Related Questions