Setting up CORS on Spring Boot along with Spring Security: A Comprehensive Guide

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()

View image description here

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.

Answer №1

Here are some suggestions to consider:

function fetchToken() {
    axios({
        method: 'post',
        url: 'http://localhost:8080/test',
        data: data
        });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Facing an ESIDIR error in NextJs, despite the fact that the code was sourced from the official documentation

For an upcoming interview, I decided to dive into learning Next.js by following the tutorial provided on Next.js official website. Everything was going smoothly until I reached this particular section that focused on implementing getStaticProps. Followin ...

Making changes to a database model (updating or replacing)

When making changes to a model in the database, is it more efficient to only update a specific field or replace all objects at the same level with that field? ...

Is it possible to create Android apps using HTML and JavaScript?

I have a strong foundation in HTML, Javascript, CSS, and AJAX, but I want to venture into Android application development. However, I lack knowledge of Java technology. Is it feasible to develop Android apps using HTML or JS? If anyone has experience wit ...

extract keys and values from an array of objects

I would like assistance with removing any objects where the inspectionScheduleQuestionId is null using JS. How can we achieve this? Thank you. #data const data = [ { "id": 0, "inspectionScheduleQuestionId": 1, ...

Displaying concealed fields using the Bootstrap table detail formatter

I am attempting to create a customized detail formatter for my table, but I am encountering several fields with underscores, such as: _id: undefined _class: undefined _data: [object Object] This occurs when I click the plus button. <head> &l ...

Exploring the seamless integration of Material UI with React version 18

I am having an issue with my background not turning black in React version 18.2.0 when using makeStyles from Material UI version 4. Despite no errors in the code, the background remains unchanged. How can I fix this problem? import './App.css'; i ...

What is the correct way to apply styles universally instead of using "*" as a selector?

With Nextron, I was able to successfully run my code, but upon opening the window, I noticed that the body tag had a margin of 8px. Although I managed to change this using the dev tools, I am unsure how to permanently apply this change in my code. When att ...

Is there a way to adjust this angular2 service to make it slightly more synchronous?

My goal is to create an Angular2 service that performs the following tasks: FTP to a remote server Read certain lines from a file Create a 'results' JSON object and return it to the component that called the service I have successfully impleme ...

Warning: Nodemailer has issued a deprecation warning regarding the outdated `punycode` module

Looking to automate daily email sending through a Gmail account, I have been experimenting with nodemailer and crafted this simple test code: const fs = require('fs'); const path = require('path'); const nodemailer = require('nodem ...

Transform Ajax response into dropdown menu option

I have made an ajax call and received HTML as a response. Now, I need to convert this output into options and add them to select tags on my webpage. <div class="views-element-container"> <div class="view view-contact-view-id-conta ...

Error in React Typescript Order Form when recalculating on change

When creating an order form with React TypeScript, users can input the quantity, unit price, and select whether the item is taxable. In this simplified example, only 1 or 2 items can be added, but in the final version, users will be able to add 10-15 item ...

Utilizing FullCalendar for showcasing comprehensive details

I'm a big fan of the fullcalendar plugin and all its amazing features. I want to enhance it by displaying more customized information for each event when in agendaWeek or agendaMonth view. Switching between views is easy, but I need help filtering out ...

Implementing a Response to an AJAX POST Request with Servlets

I have a unique situation where I need to validate a username input in a text box. The process involves sending the entered username to a server for checking if it has already been taken by another user. If the username is available, I want to change the b ...

Struggling with UI-Grid's single filter feature when dealing with intricate data structures?

I'm currently working with UI-Grid and facing a challenge while applying a filter to some complex data using their single filter example. Initially, everything runs smoothly when I use simple selectors. However, as soon as I attempt to delve one level ...

Transform a JSON object string into a usable value

I'm currently working on a function that takes a string, splits it, and then formats it using json[key][key2][key3]. The issue is that 'n' could potentially be infinite (not literally but needs to be written as such) function getJsonValue(j ...

What is Flask's approach to managing JSON data?

I am currently developing an editable table using FLASK, JSON, and jQuery. After serializing the form, I send it via $.getJSON, as shown at the bottom of my JS code: This is the JS code: $(function(){ $('tbody').on('click', &apos ...

What is the reason behind including a data string filled with a series of numbers accompanied by dashes in this ajax request?

I stumbled upon a website filled with engaging JavaScript games and was intrigued by how it saves high scores. The code snippet in question caught my attention: (new Request({ url: window.location.toString().split("#")[0], data: { ...

Effortlessly find data in an HTML table and showcase the results instantly without

I am looking for a way to implement search functionality in my table without refreshing the page. The fields above the table are used for searching and I want the results to be displayed within the same table. Here is an example of the code: <?php $for ...

Enhance the functionality of the 'validate as true' function

I have an object that resembles the following $scope.object = { Title: 'A title', Status: 'Open', Responsible: 'John Doe', Author: 'Jane Doe', Description: 'lorem ipsum dolor sit' } My aim now i ...

Retrieving an array of various responses using Axios

My current code includes a function that retrieves exchange rates for various stocks: export const getRates = (symbole1, symbole2, symbole3) => { const res = [] axios.all([ axios.get(`${baseUrl}/${symbole1}`), axios.get(`${ ...