Search code examples
spring-securityspring-bootcsrfbasic-authentication

Spring Boot web app w/ both session + CSRF & stateless Basic Auth w/o CSRF


I'm trying to stand up a Spring Boot based web server that supports both a secured session-based UI, including CSRF protection and stateless access that is authenticated via basic auth and does not require CSRF. The two use cases I'm trying to support are a standard AngularJS UI and a simple REST api that authenticates on every request.

Does anyone know how to configure this? I've seen lots of examples of using one or the other, but not both together.


Solution

  • So I finally got back to looking into this question again and it turns out the solution is nearly as simple as I expected. The solution is to have two WebSecurityConfigurerAdapter classes. This is described here:

    http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity

    Two things to be aware of when doing this are:

    1. The WebSecurityConfigurerAdapter classes must have different @Order value. So I annotated one of them with @Order(1), forcing that one to be evaluated first when processing HTTP requests. In my case it doesn't really matter which one is first, they just have to be different.
    2. The two HttpSecurity configurations need to apply to different URLs. This is done by using antMatcher() values for each one. Given that the value provided to @RequestMapping can be an array of URLs, it's still possible to have just a single REST controller method handling requests to both URLs.

    So here they are:

    @Configuration
    @EnableWebSecurity
    @Order(1)
    public class APISecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        @Order(1)
        protected void configure(HttpSecurity http) throws Exception {
    
            http.antMatcher("/api/**")
                    .authorizeRequests()
                    .anyRequest().fullyAuthenticated().and()
                    .httpBasic().and()
                    .csrf().disable();
        }
    }
    

    And

    @Configuration
    @EnableWebSecurity
    public class UISecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http.authorizeRequests()
                    .antMatchers("/ui/**").authenticated();
        }
    }