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?
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With