本文介绍了即使设置了crossorigin,仍然面临CORS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想从 Angular 应用调用 Spring API :
I want to call a Spring API from an Angular app :
login(user: User) : Observable<User> {
return this.http.post(this._baseUrl + 'users/login', user)
.map((response: Response) => {
let utilisateur = response.json();
if (utilisateur) {
sessionStorage.setItem('currentUser', JSON.stringify(utilisateur));
this.setAuthState(AuthState.LOGGED_IN);
}
return utilisateur;
});
}
这是调用的 Spring 控制器:
Here is the Spring controller called :
import com.edm.entity.*;
import com.edm.service.IHistoUserService;
import com.edm.service.IUtilisateurService;
import java.io.PrintStream;
import java.util.List;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
@Controller
@RequestMapping("gmao/users")
@CrossOrigin(origins={"*"})
public class UtilisateurController
{
@Autowired
private IUtilisateurService utilisateurService;
@Autowired
private IHistoUserService histoUserService;
...
@PostMapping("login")
public ResponseEntity<Utilisateur> login(@RequestBody Utilisateur user, UriComponentsBuilder builder) {
Utilisateur userlogin = utilisateurService.getByEmail(user.getEmail());
if (userlogin == null) {
return new ResponseEntity<Utilisateur> (HttpStatus.FORBIDDEN);
} else {
if (checkPassword(user.getPassword(), userlogin.getPassword())) {
utilisateurService.login(userlogin);
//ADD HISTORIQUE
HistoUser histo = new HistoUser();
histo.setDescription("Connexion");
histo.setUser(userlogin);
histoUserService.create(histo);
return new ResponseEntity<Utilisateur>(userlogin,HttpStatus.OK);
} else {
return new ResponseEntity<Utilisateur> (HttpStatus.FORBIDDEN);
}
}
}
...
}
在运行时我收到 CORS 错误!那么有什么问题?
At runtime I get CORS error ! So what is wrong ?
我实施了 Daniel Wosch 的回答:
I implemented Daniel Wosch's answer :
package com.edm.config;
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;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
}
}
在@Configuration 类中:
Inside a @Configuration class :
@Configuration
@PropertySource("classpath:application.properties")
public class Config implements EnvironmentAware {
@SuppressWarnings("unused")
@Autowired
private Environment env;
@Override
public void setEnvironment(final Environment environment) {
this.env = environment;
}
public ObjectMapper objectMapper(){
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
mapper.setVisibility(mapper.getSerializationConfig()
.getDefaultVisibilityChecker().withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
return mapper;
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "authorization"));
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
config.setAllowedOrigins(Collections.singletonList("*"));
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
@Value("${path.file}")
public String pathFile;
...
}
这里是 pom.xml :
Here is the pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.edm</groupId>
<artifactId>gmao</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>gmao</name>
<description>project for GMAO</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version><!--$NO-MVN-MAN-VER$-->
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>1.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version><!--$NO-MVN-MAN-VER$-->
</dependency>
...
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
但在运行时,CORS 错误仍在发生!
But at runtime the CORS error is still happening !
推荐答案
设置 Spring Security
Set Up Spring Security
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// Invoke the cors(); method on HttpSecurity otherwise cors settings are not applied on http security
http.cors();
// further stuff
}
然后实现一个cors过滤器bean
Then implement a cors filter bean
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "authorization"));
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
config.setAllowedOriginPatterns(Collections.singletonList("*"));
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
如文档所述,在调用 http.cors() 时将自动使用 Bean.
The Bean will automatically be used when invoking http.cors() as the documentation says.
这篇关于即使设置了crossorigin,仍然面临CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!