Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security : Multiple HTTP Config not working

Tags:

I am trying to use Spring Security and I have a use case where I want different login pages and different set of URLs to be secured.

Here is my configuration:

@Configuration @Order(1) public static class ProviderSecurity extends WebSecurityConfigurerAdapter{     @Override     protected void configure(HttpSecurity http) throws Exception {         http             .authorizeRequests()                 .antMatchers("/", "/home").permitAll()                 .antMatchers("/admin/login").permitAll()                 .antMatchers("/admin/**").access("hasRole('BASE_USER')")                 .and()             .formLogin()                 .loginPage("/admin/login").permitAll()                 .defaultSuccessUrl("/admin/home")                 .failureUrl("/admin/login?error=true").permitAll()                 .usernameParameter("username")                 .passwordParameter("password")                 .and()             .csrf()                                     .and()             .exceptionHandling().accessDeniedPage("/Access_Denied");                 } }   @Configuration @Order(2) public static class ConsumerSecurity extends WebSecurityConfigurerAdapter {      @Override     protected void configure(HttpSecurity http) throws Exception {         http             .authorizeRequests()                 .antMatchers("/consumer/login").permitAll()                 .antMatchers("/consumer/**").access("hasRole('BASE_USER')")                 .anyRequest().authenticated()                 .and()             .formLogin()                 .loginPage("/consumer/login").permitAll()                 .defaultSuccessUrl("/consumer/home")                 .failureUrl("/consumer/login?error=true").permitAll()                 .usernameParameter("username")                 .passwordParameter("password")                 .and().csrf()                                 .and()             .exceptionHandling().accessDeniedPage("/Access_Denied");     } } 

These classes are inner classes of another class MultipleHttpSecurityConfig that has annotation @EnableWebSecurity.

The security for admin/** is working fine, but none of the consumer/** pages are secured, no redirection is happening for login page. I've searched for other answers but none worked.

like image 529
Mohan Singh Avatar asked Nov 09 '15 05:11

Mohan Singh


People also ask

Can we have 2 WebSecurityConfigurerAdapter?

When using Java configuration, the way to define multiple security realms is to have multiple @Configuration classes that extend the WebSecurityConfigurerAdapter base class – each with its own security configuration. These classes can be static and placed inside the main config.

Is WebSecurityConfigurerAdapter deprecated?

The type WebSecurityConfigurerAdapter is deprecatedWell, it's because the developers of Spring framework encourage users to move towards a component-based security configuration.

What does EnableWebSecurity annotation do?

The @EnableWebSecurity enables the web securities defined by WebSecurityConfigurerAdapter automatically. To override web securities defined by WebSecurityConfigurerAdapter in our Java configuration class, we need to extend this class and override its methods.


2 Answers

Look at the Spring Security Reference:

@EnableWebSecurity public class MultiHttpSecurityConfig {   @Autowired   public void configureGlobal(AuthenticationManagerBuilder auth) { 1       auth           .inMemoryAuthentication()               .withUser("user").password("password").roles("USER").and()               .withUser("admin").password("password").roles("USER", "ADMIN");   }    @Configuration   @Order(1)                                                        2   public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {       protected void configure(HttpSecurity http) throws Exception {           http               .antMatcher("/api/**")                               3               .authorizeRequests()                   .anyRequest().hasRole("ADMIN")                   .and()               .httpBasic();       }   }        @Configuration                                                   4   public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {        @Override       protected void configure(HttpSecurity http) throws Exception {           http               .authorizeRequests()                   .anyRequest().authenticated()                   .and()               .formLogin();       }   } } 

1 Configure Authentication as normal

2 Create an instance of WebSecurityConfigurerAdapter that contains @Order to specify which WebSecurityConfigurerAdapter should be considered first.

3 The http.antMatcher states that this HttpSecurity will only be applicable to URLs that start with /api/

4 Create another instance of WebSecurityConfigurerAdapter. If the URL does not start with /api/ this configuration will be used. This configuration is considered after ApiWebSecurityConfigurationAdapter since it has an @Order value after 1 (no @Order defaults to last).

Your second configuration is not used, because your first configuration matches /** (no antMatcher configured). And your first configuration restricts only /admin/**, all other URLs are permitted by default.

like image 118
dur Avatar answered Sep 24 '22 04:09

dur


Your first WebSecurityConfigurerAdapter's

http             .authorizeRequests() 

matches all the URLs, limit it to only URLs start with /admin by using antMatcher:

@Configuration @Order(1) public static class ProviderSecurity extends WebSecurityConfigurerAdapter{     @Override     protected void configure(HttpSecurity http) throws Exception {         http             .antMatcher("/admin/**")                 .authorizeRequests()                 .antMatchers("/admin/login").permitAll()                 .antMatchers("/admin/**").access("hasRole('BASE_USER')")                 .and()                  ... 
like image 34
DiveInto Avatar answered Sep 23 '22 04:09

DiveInto