Reputation: 2250
I need to implement CSRF protection to my backend. I am using the below configurations. But applications allow Post and Get requests without CSRF token.
@Slf4j
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig {
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.csrf(csrf -> csrf.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()))
.authorizeExchange()
.anyExchange().authenticated()
.and().oauth2ResourceServer().jwt();
return http.build();
}
}
include the actual CSRF token in the HTTP request
@ControllerAdvice
public class SecurityControllerAdvice {
@ModelAttribute
Mono<CsrfToken> csrfToken(ServerWebExchange exchange) {
Mono<CsrfToken> csrfToken = exchange.getAttribute(CsrfToken.class.getName());
return csrfToken.doOnSuccess(token -> {
exchange.getAttributes()
.put(CsrfRequestDataValueProcessor.DEFAULT_CSRF_ATTR_NAME, token);
});
}
}
I tried the API using postman. But this is not working for me.
Spring version
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/>
</parent>
Dependencies:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Final target: My frontend is Vuejs + nuxtjs. Can someone help me to find the best way for implement this?
Upvotes: 2
Views: 1465
Reputation: 6248
By using the oauth2ResourceServer()
DSL, you are telling Spring Security that you are not using cookie-based authentication, therefore you do not need CSRF protection.
If you take a look at the OAuth2ResourceServerConfigurer#registerDefaultCsrfOverride
you will notice that it doesn't apply the CSRF token validation to requests that contain a Bearer
token, by using the BearerTokenRequestMatcher
.
private void registerDefaultCsrfOverride(H http) {
CsrfConfigurer<H> csrf = http.getConfigurer(CsrfConfigurer.class);
if (csrf != null) {
csrf.ignoringRequestMatchers(this.requestMatcher);
}
}
CSRF exploits the browser behavior that automatically attaches the Cookies for the request, so I can trick users from my website www.malicioussite.example
to click on a button and send a request to www.fakebank.example/transferMoneyToMe
.
When you are using the Authorization
header to send the JWT, the browser does not know about the access token, and therefore, will not attach the header automatically.
You can dive more deeply into this behavior starting from this answer https://security.stackexchange.com/questions/189326/do-i-need-csrf-protection-in-this-setup-with-a-rest-api-backed-with-oauth2-and-a
Upvotes: 8