8

My understanding of spring security's configuration http.anyRequest().authenticated() is that any request must be authenticated otherwise my Spring app will return a 401 response.

Unfortunately my spring app does not behave this way, but lets unauthenticated requests pass through.

This is my Spring Security Configuration:

@Configuration
@Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationTokenFilter authenticationTokenFilter;

    @Autowired
    private TokenAuthenticationProvider tokenAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
                .antMatcher("/*")
                .authenticationProvider(tokenAuthenticationProvider)
                .authorizeRequests()
                .anyRequest().authenticated();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers("/index.html")
                .antMatchers("/error")
                .antMatchers("/swagger-ui.html")
                .antMatchers("/swagger-resources");
    }
}

The AuthenticationTokenFilter takes a JWT token from the request, checks its validity, creates an Authentication from it, and sets the authentication in the SecurityContextHolder. If no token is provided, the SecurityContextHolder.getContext().getAuthentication() remains null.

My Controller looks like this:

@RestController
@RequestMapping("/reports")
@Slf4j
public class ReportController {

    @RequestMapping()
    @ResponseBody
    public List<String> getIds() {
        log.info(SecurityContextHolder.getContext().getAuthentication());
        return Collections.emptyList();
    }

}

When running a curl request against the endpoint without a token, I simply get a valid response:

-> curl 'localhost:8080/reports/'
[]

When debugging, I can see that the SecurityContextHolder.getContext().getAuthentication() is null.

Any ideas?

user152468
  • 3,202
  • 6
  • 27
  • 57

1 Answers1

16

It actually works as expected and that is due how you have written your configuration.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
            .antMatcher("/*")
                .authenticationProvider(tokenAuthenticationProvider)
                .authorizeRequests()
                .anyRequest().authenticated();
}

This is your own configuration, with some additional indentation by me. When you write an antMatcher here that means everything following that antMatcher applies to the path/expression written in there (see the Javadoc of AntPathMatcher).

Now as you have written /* this applies to /reports it doesn't apply to /reports/ (yes that last / matters!).

What you probably intended to write is

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
            .antMatcher("/**")
                .authenticationProvider(tokenAuthenticationProvider)
                .authorizeRequests()
                .anyRequest().authenticated();
}

Notice the /** instead of /*. However that basically is the same as leaving out the antMatcher and simply writing

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .addFilterBefore(authenticationTokenFilter, BasicAuthenticationFilter.class)
            .authenticationProvider(tokenAuthenticationProvider)
            .authorizeRequests()
            .anyRequest().authenticated();
}
informatik01
  • 16,038
  • 10
  • 74
  • 104
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • Can you give explanation to my qn as well : https://stackoverflow.com/questions/55894199/explanation-regarding-spring-security-url-based-security/55894749#55894749 – ASharma7 Apr 29 '19 at 05:28