I have a Spring Boot REST API. Due to a security policy I need to have CSRF protection enabled for endpoints accessed by the browser. However, this API will also be accessed by non-browsers. Is there a way I can create two sets of endpoints, one accessible by browsers only with CSRF enabled and the other accessible by non-browsers only with CSRF disabled?
CodePudding user response:
When you configure your CSRF protection using the DSL, like this http.csrf()...
you can tell which requests you want the CSRF protection to be applied by passing a RequestMatcher
, like so:
http.csrf(csrf -> csrf.requireCsrfProtectionMatcher(new MyBrowserRequestMatcher()));
And your implementation of RequestMatcher
could verify if the HttpServletRequest
contains the header X-Requested-With: XMLHttpRequest
or check the User-Agent
.
Just keep in mind that the headers can be changed and you have no guarantee that the request actually come from a browser or non-browser app.
CodePudding user response:
I think you could have separate URL bases for the browser requests and API requests.
For example, you could have all the endpoints that are to be queried by non-browsers under /api/...
and in your SpringBootSecurityConfiguration
class and configure(HttpSecurity http)
method you could conditionally disable CSRF with http.csrf().disable();
if the pattern matches (great tutorial can be found here)
Edit: here is another answer that might be useful.