Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security Configuration anyRequest().authenticated() not working as expected

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?

like image 351
user152468 Avatar asked Dec 18 '22 23:12

user152468


1 Answers

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();
}
like image 179
M. Deinum Avatar answered May 28 '23 14:05

M. Deinum