CORS: Response to preflight request doesn't pass access control check: it does not have HTTP ok status
I can get the TOKEN from my application, using PostMan, as follows.
This works perfectly, and me return the Token.
However when I try to make the same request, using Axios, in my application with Vue @ Cli I get the following error:
I am mounting the Axios request like this:
axios({
url: '/oauth/token',
method: 'post',
baseURL: 'http://prog06:8080',
headers: { 'Authorization': 'Basic bWFzdGVyOjEyMzQ1', 'Content-Type': 'application/x-www-form-urlencoded', 'scope': 'password', },
data: {
username: 'user1',
password: 'user1'
}
}).then(result => {
console.log(result)
})
Configurações
Basic
I'm going through the following value master:12345
in Base64.
data
I'm passing the username
and password
from the user.
The backend is in Java Spring Boot:
Pom.xml
<dependencies>
<!-- Segurança | Início -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<!-- Segurança | Fim -->
SecurityConfig.java
/ / Edit02
package com.mfac.config;
import java.util.Arrays;
import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@EnableWebSecurity
@EnableAuthorizationServer
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
@CrossOrigin
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
CorsConfigurationSource corsConfigurationSource(){
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
How can I fix this problem ? because the request for oauth/token
by postMan works, now with Axios returns the CORS error cited above.
2 answers
You have to release the CORS on the server, it works in postman because the browser when going to make a request sends first an OPTIONS to the server to know what is released as you have not configured this error occurs ai console, to release it has n modes:
From what I've seen of your pom is going to be this mode the easiest to implement
Spring Security:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
//other config
}
//Adicionar esse Bean no na sua classe WebSecurityConfigurerAdapter e configurar o que você quer liberar
@Bean
CorsConfigurationSource corsConfigurationSource(){
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
In each class / controller:
@CrossOrigin(origins = "*", allowedHeaders = "*")
@Controller
public class HomeController{
@GetMapping(path="/")
public String homeInit(Model model) {
return "home";
}
}
In one method specific:
@Controller
public class HomeController{
@CrossOrigin(origins = "*", allowedHeaders = "*")
@GetMapping(path="/")
public String homeInit(Model model) {
return "home";
}
}
Overwriting no method:
@Controller
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class HomeController{
@CrossOrigin(origins = "http://example.com")
@GetMapping(path="/")
public String homeInit(Model model) {
return "home";
}
}
Globally with WebMvcConfigurerAdapter:
@Configuration
@EnableWebMvc
public class CorsConfiguration extends WebMvcConfigurerAdapter{
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST");
}
}
Globally with WebMvcConfigurer:
@Configuration
public class CorsConfiguration{
@Bean
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
}
Using a filter
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {
@Override
public void init(FilterConfig fc) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN, ");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, resp);
}
}
@Override
public void destroy() {
}
}
Removed and adapted from: https://howtodoinjava.com/spring5/webmvc/spring-mvc-cors-configuration /
As I answered in more detail in this answer to @Dup, I believe that the filter configuration is unnecessary, since Spring Boot already provides resources to treat CORS.
To change the headers, this can be done using the following configuration:
@Configuration
public class CorsConfig {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("*"));
config.setAllowCredentials(true);
config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return configSource;
}
}