Message Retrieval 403 Forbidden with Spring Download (VueJS and Axios Frontend)

I had a problem with CORS, and I tried everything I could find on Stack Overflow, and basically everything I found on Google, and I had no luck.

So, I have user authentication on my server, and I have a login page in my interface. I connected the login page using Axios so that I could send a request and tried to log in, but I continued to receive errors such as "Pre-Professional Request", so I fixed it and then started to receive the message "Post 403 Forbidden".

It looked like this:

POST http://localhost:8080/api/v1/login/ 403 (Forbidden) 

Even trying to log in using Postman does not work, so something is clearly wrong. The class file below will be published

On my backend, I have a class called WebSecurityConfig that applies to all CORS stuff:

 @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsServiceImpl userDetailsService; @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedMethods("GET", "POST", "HEAD", "PUT", "DELETE", "OPTIONS"); } }; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); // TODO: lock down before deploying config.addAllowedHeader("*"); config.addExposedHeader(HttpHeaders.AUTHORIZATION); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } @Override protected void configure(HttpSecurity http) throws Exception { http.headers().frameOptions().disable(); http .cors() .and() .csrf().disable().authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/h2/**").permitAll() .antMatchers(HttpMethod.POST, "/api/v1/login").permitAll() .anyRequest().authenticated() .and() // We filter the api/login requests .addFilterBefore(new JWTLoginFilter("/api/v1/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class); // And filter other requests to check the presence of JWT in header //.addFilterBefore(new JWTAuthenticationFilter(), // UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // Create a default account auth.userDetailsService(userDetailsService); // auth.inMemoryAuthentication() // .withUser("admin") // .password("password") // .roles("ADMIN"); } } 

In our interface, written in VueJS and using Axios to invoke

 <script> import { mapActions } from 'vuex'; import { required, username, minLength } from 'vuelidate/lib/validators'; export default { data() { return { form: { username: '', password: '' }, e1: true, response: '' } }, validations: { form: { username: { required }, password: { required } } }, methods: { ...mapActions({ setToken: 'setToken', setUser: 'setUser' }), login() { this.response = ''; let req = { "username": this.form.username, "password": this.form.password }; this.$http.post('/api/v1/login/', req) .then(response => { if (response.status === 200) { this.setToken(response.data.token); this.setUser(response.data.user); this.$router.push('/dashboard'); } else { this.response = response.data.error.message; } }, error => { console.log(error); this.response = 'Unable to connect to server.'; }); } } } </script> 

Therefore, when I debugged using the Chrome (Network) tools, I noticed that the OPTIONS request was passing as shown below:

Request options through

Here is the image of the POST error:

POST request error

Here is another class that processes an OPTIONS request (JWTLoginFilter, as specified in WebSecurityConfig):

 public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter { public JWTLoginFilter(String url, AuthenticationManager authManager) { super(new AntPathRequestMatcher(url)); setAuthenticationManager(authManager); } @Override public Authentication attemptAuthentication( HttpServletRequest req, HttpServletResponse res) throws AuthenticationException, IOException, ServletException { AccountCredentials creds = new ObjectMapper() .readValue(req.getInputStream(), AccountCredentials.class); if (CorsUtils.isPreFlightRequest(req)) { res.setStatus(HttpServletResponse.SC_OK); return null; } return getAuthenticationManager().authenticate( new UsernamePasswordAuthenticationToken( creds.getUsername(), creds.getPassword(), Collections.emptyList() ) ); } @Override protected void successfulAuthentication( HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication auth) throws IOException, ServletException { TokenAuthenticationService .addAuthentication(res, auth.getName()); } } 
+5
source share
2 answers

I had the same problem when a GET request was given, and still the status 403 answered the POST request.

I found that for my case this was due to the inclusion of CSRF protection by default.

A quick way to verify this is to disable CSRF:

 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // … @Override protected void configure(HttpSecurity http) throws Exception { // … http.csrf().disable(); // … } // … } 

Additional information about Spring-Security .

Remember that disabling CSRF is not always the right answer, as it exists for security purposes.

0
source

You should not disable CSRF according to Spring's security documentation, except for a few special cases. This code will put the CSRF header in VUE. I used the vue resource.

 //This token is from Thymeleaf JS generation. var csrftoken = [[${_csrf.token}]]; console.log('csrf - ' + csrftoken) ; Vue.http.headers.common['X-CSRF-TOKEN'] = csrftoken; 

Hope this helps.

0
source

Source: https://habr.com/ru/post/1271441/


All Articles