0

I'm building an WebApi with Spring and client with Reactjs. I'm trying to do a POST request to authenticate with OAuth2, against the WebApi, but I keep getting

Response for preflight has invalid HTTP status code 401

WebSecurityConfigurerAdapter:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(false); //updated to false
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS).permitAll()
                .antMatchers("/**").authenticated()
                .and()
                .httpBasic();
    }
}

My request is:

fetch( 
      this.getAuthEndpoint('password'), {
        method:'post',
      headers: {
        'Access-Control-Allow-Origin': '*', 
        'Authorization': 'Basic dG9ucjpzZWNyZXQ='
      },
      body: JSON.stringify({
        'password': credentials.password,
        'username': credentials.username,
        'grant_type': 'password',
        'scope': 'read write',
        'client_secret': Config.clientSecret,
        'client_id': Config.clientId
      })})
      .then(response => {
        this.saveTokens(response.data);

        return axios.get(Config.apiUrl + '/me');
      })
      .then(response => {
        this.loginSuccess(response.data.user);
      })
      .catch(response => {
        this.loginError(response);
      });

And the request/response status is: enter image description here

Andre Roque
  • 503
  • 1
  • 9
  • 31

3 Answers3

1

Try doing http.cors().. like

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors()....
}

Reference https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

This will add a CORS filter and return immediately instead of passing requests into security filters.

shanmugaprabhu
  • 186
  • 1
  • 9
1

If you are using Springboot ,add following code into application.java

  package com.khan.vaquar;

import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@SpringBootApplication
public class SpringBootGraphqlApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootGraphqlApplication.class, args);
    }

    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Collections.singletonList("*"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        config.setAllowedMethods(Arrays.stream(HttpMethod.values()).map(HttpMethod::name).collect(Collectors.toList()));
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}
vaquar khan
  • 10,864
  • 5
  • 72
  • 96
0

Add a CorsFilter

@Component    
@Order(Ordered.HIGHEST_PRECEDENCE)    
public class SimpleCorsFilter implements Filter {

//private final Logger log = LoggerFactory.getLogger(SimpleCorsFilter.class);
    public SimpleCorsFilter() {
        System.out.println("SimpleCORSFilter init");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, x-auth-token");

        System.out.println("cors filter called");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
         response.setStatus(HttpServletResponse.SC_OK);
        }else {
            chain.doFilter(req, res);
       }
    // chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

}
Teshan
  • 351
  • 7
  • 10