I was trying to Send Bearer authentication token to from Front-end to Back-end then I was getting CORS error.
I am using JWT token for authentication in Backend Built using Spring Boot.
I have configured the Security Configuration
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(customizer -> customizer.disable())
.authorizeHttpRequests(request -> request
// Public Endpoints (No Authentication Required)
.requestMatchers("auth/register", "auth/login", "auth/google", "/products/**").permitAll()
// User-Specific Endpoints (Authentication Required)
.requestMatchers( "/orders/**", "/shipping/**","/cart/**").hasRole("USER")
// Admin-Specific Endpoints (Authentication & Role Required)
.requestMatchers("/admin/**").hasRole("ADMIN")
// Any Other Requests
.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exception -> exception.authenticationEntryPoint(new CustomAuthenticationEntryPoint()))
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
jwtFilter:
// Overriding the doFilterInternal method to implement the logic for validating JWT token
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization"); // Extracting the Authorization header from the request
String token = null; // Variable to store the JWT token
String username = null; // Variable to store the username extracted from the token
System.out.println("Authorization Header:"+authHeader);
// Checking if the Authorization header exists and starts with "Bearer " indicating a JWT token is present
if(authHeader != null && authHeader.startsWith("Bearer ")) {
token = authHeader.substring(7); // Extracting the token part after "Bearer "
username = jwtService.getUsernameFromToken(token); // Extracting the username from the token using the JWT service
}
// Checking if the token is not blacklisted, the username is not null, and the user is not already authenticated
if(!tokenBlacklistedRepo.existsByToken(token) && username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
// Dynamically loading the user details from the application context using the username extracted from the token
UserDetails userDetails = context.getBean(MyUserDetailsService.class).loadUserByUsername(username);
// Validating the token using the JWT service and user details
if(jwtService.validateToken(token, userDetails)) {
// Creating an authentication token if the JWT is valid, which will hold the user details and authorities (permissions)
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
// Setting the details of the authentication token, such as the IP address, session details, etc.
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// Storing the authentication token in the security context, marking the user as authenticated
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
// Proceeding with the filter chain to allow the request to continue to the next filter or endpoint
filterChain.doFilter(request, response);
}
When I am making a request using Authorization token from Postman then I am getting the authorization token in JWTfilter class but when I am making a request from ReactJS then Getting CORS error.
Also, I have Configured the CORSFIlter as follows:
@Component
public class CorsFilter extends OncePerRequestFilter {
private final CorsProcessor processor = new DefaultCorsProcessor();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println(request);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(Arrays.asList("http://localhost:5173")); // Frontend origin
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "Authorization"));
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
config.addExposedHeader("Authorization");
source.registerCorsConfiguration("/**",config);
CorsConfiguration corsConfiguration = source.getCorsConfiguration(request);
boolean isPreFlight = CorsUtils.isPreFlightRequest(request);
// Handle preflight (OPTIONS) request
if (isPreFlight) {
// Set the necessary headers for preflight request
response.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "3600"); // Cache preflight response for 1 hour
response.setStatus(HttpServletResponse.SC_OK);
return; // End the filter chain for OPTIONS request
}
boolean isvalid = this.processor.processRequest(corsConfiguration, request, response);
if(!isvalid || CorsUtils.isPreFlightRequest(request)){
return;
}
filterChain.doFilter(request, response);
}
}
2
Answers
Thank you for the support. This issue has been solved.
Actually, I read an article on Medium that told me about the way to resolve CORS errors in the Spring application by allowing headers, origins, and many other things. That resolved the issue, and login registration functionality was working fine.
But when I implemented the Cart Page, which is a secured route and requires an authentication token to be sent with the request, then the authorization token was not reaching the Spring application.
So, I read the documentation of Spring and looked for many solutions on YouTube. After some time, I found a video on YouTube.
Youtube LInk: https://youtu.be/uMJnAxapF7E?si=u5myiwDTOIVmpxqk
So what I did, I Still configured the Cors setting but this time, I configuired WebMvcConfigure as FOllows:
public class WebConfig {
}
One more thing:
Step 1: Remove all CORS configuration in all places. Assure that it works.
Step 2: After removing all CORS configuration, then set it in one and only place.
Focus at this line
Make sure it works.
Step 3: Then you fine tune it
comment, remove this line what created at the below step.
Focus at this line
Reference: https://docs.spring.io/spring-security/reference/reactive/integrations/cors.html