本文介绍了即使设置了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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 23:27