I'm encountering an issue with CORS. Here's the security configuration I have:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
CustomUserDetailsService userDetailsService;
@Autowired
private CustomJwtAuthenticationFilter customJwtAuthenticationFilter;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(HttpSecurity http) throws Exception {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
corsConfiguration.setAllowedOrigins(List.of("*"));
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PUT","OPTIONS","PATCH", "DELETE"));
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setExposedHeaders(List.of("Authorization"));
http.csrf().disable()
.authorizeRequests()
.antMatchers("/helloadmin").hasRole("ADMIN")
.antMatchers("/hellouser").hasAnyRole("USER","ADMIN")
.antMatchers("/techshop/web/v1/product/save").hasRole("ADMIN")
.antMatchers("techshop/web/v1/product").hasAnyRole("USER", "ADMIN")
.antMatchers("techshop/web/v1/product/{id}").hasRole("ADMIN")
.antMatchers("/authenticate").permitAll().anyRequest().authenticated()
.and().exceptionHandling()
//if any exception occurs call this
.authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//Add a filter to validate the tokens with every request
http.addFilterBefore((Filter) customJwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter.class);
}
}
Additionally, I have the following controllers:
@RestController
@RequestMapping(value = "")
public class AuthenticationController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private JwtUtil jwtUtil;
@PostMapping(path = "/authenticate", consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest request) throws Exception {
try{
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
request.getUsername(), request.getPassword()));
} catch (DisabledException e) {
throw new Exception("USER_DISABLE", e);
} catch (BadCredentialsException e){
throw new Exception("INVALID_CREDENTIALS", e);
}
final UserDetails userDetails = customUserDetailsService.loadUserByUsername(request.getUsername());
final String token = jwtUtil.generateToken(userDetails);
return ResponseEntity.ok(new AuthenticationResponse(token));
}
}
And:
@RestController
@RequestMapping("techshop/web/v1")
public class ProductController {
@Autowired
private ProductServiceI productService;
@PostMapping(value = "/product/save", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> save(@RequestBody ProductDto request){
productService.save(request);
return ResponseEntity.ok(Boolean.TRUE);
}
@GetMapping(value = "/product", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> findAll(){
return ResponseEntity.ok(productService.findAll());
}
@PutMapping(value = "/product/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> updateProduct(@PathVariable("id") int id, @RequestBody ProductDto request){
productService.update(request, id);
return ResponseEntity.ok(Boolean.TRUE);
}
@DeleteMapping(value = "/product/{id}")
public ResponseEntity<Object> deleteById(@PathVariable("id") int id){
productService.deletedById(id);
return ResponseEntity.ok(Boolean.TRUE);
}
}
When I send the following request, the browser displays a CORS error:
let data = {
username: "admin",
password: "admin"
}
const getToken = () => {
axios({
method: 'post',
url: 'localhost:8080/test',
data: data
});
}
getToken()
I've attempted various solutions, including using the @CrossOrigin("*") annotation, lambdas, and a WebConfig Bean extending corsConfigurer, but none have resolved the issue. Any assistance would be greatly appreciated.