I have a React front-end application with Java/SpringBoot backend. Prior to adding Spring-Security dependency my rest calls were working fine. However I now want to start using users and having a sign-up/login page, so tutorials were showing to use spring-security. My ultimate goal is to have a react login page that sends a call to my back-end to authenticate their username/password combination and creates a session for them with cookies. Eventually I will host this website on AWS, so if there are settings that I should change to set me up for that, please let me know.
Currently what is happening is I am getting a 403 error, and my X-XSRF-TOKEN header is showing undefined.
Here is my SecurityConfig.java:
package com.allyoucanexercise.back_end.helpers;
import .springframework.context.annotation.Bean;
import .springframework.context.annotation.Configuration;
import .springframework.security.config.annotation.web.builders.HttpSecurity;
import .springframework.security.config.http.SessionCreationPolicy;
import .springframework.security.web.SecurityFilterChain;
import .springframework.security.web.csrf.CookieCsrfTokenRepository;
import .springframework.web.cors.CorsConfiguration;
import java.util.List;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.configurationSource(request -> {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(List.of("http://localhost:3000"));
config.addAllowedHeader("*");
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
return config;
}))
.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.ALWAYS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated())
.formLogin(form -> form.disable())
.httpBasic(basic -> basic.disable());
return http.build();
}
}
Here are my application.properties:
spring.application.name=back-end
spring.sql.init.mode=always
# spring.datasource.initialize=true
server:
error:
include-message: always
include-binding-errors: always
server.servlet.session.cookie.http-only=true
# Enable in production (for HTTPS):::
# server.servlet.session.cookie.secure=true
Here is how I am calling my backend from my front-end:
const getExercisesByGroup = async () => {
const csrfToken = Cookies.get('XSRF-TOKEN'); // Read the CSRF token from the cookie
try {
const response = await axios.get(`http://localhost:8080/api/exercises/group/${exerciseGroup}`, {
headers: {
'X-XSRF-TOKEN': csrfToken,
},
withCredentials: true,
});
setExercisesByGroup(response.data);
} catch (error) {
console.error("Error fetching exercises:", error);
}
};