我如何知道服务器或客户端是否未通过Cors请求?

时间:2018-11-22 02:07:46

标签: ajax spring spring-mvc spring-boot cors

因此,我正在使用Springtoolsuite创建Restful Web服务,也正在创建Rest Client。我现在可以运行该服务,并让Postman既给我期望的结果,又运行内部的Spring浏览器并进行适当的操作。

但是,如果我随后在Springs浏览器之外加载html文件,却在Mozilla和Chrome中遇到“ CORS请求未成功”和“ CORS预检通道未成功”的典型CORS错误,则得到403的OPTIONS和CORS策略已阻止从来源“空”访问“ http://localhost:8080/ ..处的XMLHttpRequest。”:对预检请求的响应未通过访问控制检查:没有“ Access-Control-Allow-Origin”头存在于请求的资源上。”这也是CORS问题。

localhost:8080是我选择的URL,因为当我将项目作为Spring Boot应用程序运行时,Apache Tomcat在此端口上启动服务。

我现在不确定的是如何找出我在Rest Client中发出的措辞不佳的请求,还是我的服务器代码出现问题,例如,据说错误可能来自多次预检,所以我不确定我可能正在这样做。

首先是服务器代码:

package de.TeamCAM.textory.rest_interface;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.servlet.http.HttpServletResponse;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Authorization;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import multex.Exc;
import static multex.MultexUtil.create;
import de.TeamCAM.textory.domain.*;
import de.TeamCAM.textory.domain.imports.*;



@CrossOrigin(origins = "http://localhost:8080")
@RestController
@Transactional
public class ApplicationController {


     private final KapitelRepository kapitelRepository;
        private final String className = getClass().getSimpleName();

        @Autowired
        public ApplicationController(final KapitelRepository kapitelRepository) {
            this.kapitelRepository = kapitelRepository;
        }    
@GetMapping(path = "/Kategorie/Welt/Kapitel/{kapitelname}")
    public ResponseEntity<KapitelResource> findeEinKapitel(@PathVariable String kapitelname,
            @ApiParam(hidden = true) final HttpMethod method, final WebRequest request, HttpServletResponse res) {
        _print(method, request);
         res.setHeader("Access-Control-Allow-Origin", "*");
         res.setHeader("Access-Control-Allow-Methods", "*");
        final Kapitel kapitel;
        kapitel = kapitelRepository.find(kapitelname);
        if(kapitel != null) {
        return new ResponseEntity<>(new KapitelResource(kapitel), HttpStatus.OK);}
        else return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

@RequestMapping(method = RequestMethod.OPTIONS, value="/**")
        public void manageOptions(HttpServletResponse response)
        {
         response.setHeader("Access-Control-Allow-Origin", "*");
         response.setHeader("Access-Control-Allow-Methods", "*");
        } }

这是处理请求的Apllicationcontroller。我也有一个安全类,我尝试以某种方式修改安全类,以解决所有可能性和CORS问题。

package de.TeamCAM.textory.rest_interface;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityBuilder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;


@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private static final String CLIENT_ROLE = "CLIENT";
    private static final String BANK_ROLE = "BANK";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers("/**").permitAll()
            .antMatchers("/bank/**").hasRole(BANK_ROLE)
            .antMatchers("/client/**").hasRole(CLIENT_ROLE)
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers(HttpMethod.OPTIONS, "file:///E:/se2/spring-ddd-bank/src/main/resources/static/kapitel.html").permitAll()

            .antMatchers(
                    HttpMethod.GET,
                    "/v2/api-docs",
                    "/swagger-resources/**",
                    "/swagger-ui.html**",
                    "/webjars/**",
                    "favicon.ico"
            ).permitAll()
            .anyRequest().authenticated()
            .and().httpBasic() 
            .and().csrf().disable()
            ;
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    private static final List<String> predefinedUsernames = Arrays.asList("bank", "hans", "nina", "fritz", "lisa");


    @Autowired
    public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
        final InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication = auth.inMemoryAuthentication();
        for(final String username: predefinedUsernames) {
            final String role = username.equalsIgnoreCase(BANK_ROLE) ? BANK_ROLE : CLIENT_ROLE;
            inMemoryAuthentication.withUser(username).password(username).roles(role);
        }
    }

    public List<String> predefinedUsernames(){
        return predefinedUsernames;
    }

}

另外根据另一个stackoverflow答案,我创建了另一个类来添加cors支持

package de.TeamCAM.textory.rest_interface;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}`

这也没有帮助,我还根据其他答案添加了一些依赖项,现在我的pom.xml如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>

    <name>Spring DDD Bank</name>
    <groupId>de.bht-berlin.knabe</groupId>
    <artifactId>spring-ddd-bank</artifactId>
    <version>0.1-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <aspectj.version>1.8.9</aspectj.version>
        <derby.version>10.12.1.1</derby.version>
        <multexVersion>8.3</multexVersion>
        <swagger.version>2.8.0</swagger.version>
        <messageTextFile>MessageText.properties</messageTextFile>
    </properties>
    <dependencies>
        <!-- Experiment Knabe 2018-11-15: Serve Web Content, see https://spring.io/guides/gs/serving-web-content/ -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- According to https://spring.io/guides/gs/rest-hateoas/ -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
        <!-- According to https://spring.io/guides/gs/securing-web/ -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- Derby Database (in-memory in test suite, or in-directory in production 
            code) -->
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
        </dependency>
        <!-- For offering the Derby network server when the REST server is running: -->
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbynet</artifactId>
            <version>${derby.version}</version>
        </dependency>
        <!-- For downloading the Derby Client Driver: -->
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbyclient</artifactId>
            <version>${derby.version}</version>
            <!-- Install artifact into the local repo, so that a database browser 
                can pick it up, but do not deliver it with the product: -->
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>de.tfh-berlin.knabe</groupId>
            <artifactId>multex</artifactId>
            <version>${multexVersion}</version>
        </dependency>
        <!-- Following http://www.mojohaus.org/aspectj-maven-plugin/usage.html -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
    <groupId>com.thetransactioncompany</groupId>
    <artifactId>cors-filter</artifactId>
    <version>1.3.2</version>
</dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- Disable Maven Compiler Plugin for production sources following https://stackoverflow.com/questions/14614446/how-do-i-disable-the-maven-compiler-plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-compile</id>
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>
            <!-- Use AspectJ Maven Plugin instead for compiling production sources 
                following http://www.mojohaus.org/aspectj-maven-plugin/usage.html -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.10</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>       <!-- use this goal to weave all your main classes -->
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <complianceLevel>${java.version}</complianceLevel>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <dependencies>
                    <!-- Avoid AspectJ version clashes between 1.8.9 and 1.8.10 following 
                        https://stackoverflow.com/questions/41646801/maven-aspectj-weaving-for-java8 -->
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjweaver</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <executions>
                    <execution>
                        <!-- Here used for extraction of exception message texts in the reference 
                            language from the exception Javadoc comments. -->
                        <goals>
                            <goal>javadoc</goal>
                        </goals>
                        <!-- <phase>process-classes</phase> -->
                        <phase>compile</phase>
                        <configuration>
                            <!-- Specific configuration for the messages report -->
                            <doclet>multex.tool.ExceptionMessagesDoclet</doclet>
                            <docletArtifact>
                                <groupId>de.tfh-berlin.knabe</groupId>
                                <artifactId>multex</artifactId>
                                <version>${multexVersion}</version>
                            </docletArtifact>
                            <useStandardDocletOptions>false</useStandardDocletOptions>
                            <show>private</show>
                            <verbose>false</verbose>
                            <debug>false</debug>
                            <additionalparam>
                                -out
                                ${project.build.directory}/classes/${messageTextFile}
                            </additionalparam>
                            <!-- For the project-reports page -->
                            <name>ExceptionTexts</name>
                            <description>Extraction of Exception Message Texts from Source
                                Code</description>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- Java Code Coverage analyzer. See https://www.petrikainulainen.net/programming/maven/creating-code-coverage-reports-for-unit-and-integration-tests-with-the-jacoco-maven-plugin/ -->
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.9</version>
                <executions>
                    <!-- Prepares the property pointing to the JaCoCo runtime agent, which 
                        is passed as VM argument, when the Maven Surefire plugin is executed. -->
                    <execution>
                        <id>pre-unit-test</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <!-- Sets the path to the file which contains the execution data. -->
                            <destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
                            <!-- Sets the name of the property containing the settings for the 
                                JaCoCo runtime agent. -->
                            <propertyName>surefireArgLine</propertyName>
                        </configuration>
                    </execution>
                    <!-- Ensures that the code coverage report for unit tests is created 
                        after unit tests have been run. -->
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <!-- Sets the path to the file which contains the collected execution 
                                data. -->
                            <dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
                            <!-- Sets the output directory for the code coverage report. -->
                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <!-- Sets the VM argument line for test runs in Surefire, created by 
                        the upper prepare-agent goal of the jacoco-maven-plugin. -->
                    <argLine>${surefireArgLine}</argLine>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <!--This plugin's configuration is used to store Eclipse m2e settings 
                    only. It has no influence on the Maven build itself. -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>
                                            org.apache.maven.plugins
                                        </groupId>
                                        <artifactId>
                                            maven-javadoc-plugin
                                        </artifactId>
                                        <versionRange>
                                            [2.9.1,)
                                        </versionRange>
                                        <goals>
                                            <goal>javadoc</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>
                                            org.apache.maven.plugins
                                        </groupId>
                                        <artifactId>
                                            maven-dependency-plugin
                                        </artifactId>
                                        <versionRange>
                                            [3.0.2,)
                                        </versionRange>
                                        <goals>
                                            <goal>sources</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>2.10.4</version>
                <configuration>
                    <show>private</show>
                </configuration>
            </plugin>
            <!-- Do not look for possible repositories for each dependency in order 
                to speed up project site generation. See https://www.mkyong.com/maven/maven-site-build-is-very-slow-dependency-report/ -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
                </configuration>
            </plugin>
        </plugins>
    </reporting>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository><!-- For current MulTEx: -->
            <id>bht-knabe-repository</id>
            <name>BHT Knabe Maven 2 repository</name>
            <url>http://public.beuth-hochschule.de/~knabe/mvn-repo/</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

我是在没有web.xml文件的情况下执行此操作的,因此,有关如何更改web.xml以添加CORS支持的所有答案当然也没有帮助。我认为,服务器端的所有这些都会使CORS支持或停止对CORS的支持。

html几乎没有害处,唯一相关的行是

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="allstar.js" defer></script>

我在脑海中,把它们放在身体的尽头并没有改变。 这两个相关的js文件如下:

let speichern = document.getElementById("speichern");

    var put = document.getElementById("put");
    var dele = document.getElementById("delete");
    var post = document.getElementById("post");
    var get = document.getElementById("get");
    let form = document.getElementById("formSubmit");    
    let kapitelName = document.getElementsByName("kapitelName")[0];
    let kapitelInhalt = document.getElementsByName("kapitelInhalt")[0];
    let istEnde = document.getElementById("istEnde");
    let bild = document.getElementsByName("bild");

    let name = {};
    let inhalt = {};

    kapitelName.oninput = function() {
        name.value = kapitelName.value;
        console.log(name);
    }
    kapitelInhalt.oninput = function() {
        inhalt.value = kapitelInhalt.value;
        console.log(inhalt);
    }
    istEnde.onchange = function() {
        console.log("The checkbox was checked.");
    }

    var script = document.createElement('script');
    script.onload = function () {}


    document.getElementById("put").onclick = function() {
        myputFunction()  
    }

    function myputFunction() {

        script.src = "trueput.js";
        document.head.appendChild(script);
    }

    document.getElementById("get").onclick = function() {
        mygetFunction()  
    }

 function mygetFunction() {

        script.src = "trueget.js";
        document.head.appendChild(script);
    }

 document.getElementById("post").onclick = function() {
    mypostFunction()  
 }

 function mypostFunction() {

    script.src = "truepost.js";
    document.head.appendChild(script);
 }

 document.getElementById("delete").onclick = function() {
        mydeleteFunction()  
     }

     function mydeleteFunction() {

        script.src = "truedelete.js";
        document.head.appendChild(script);
     }

处理不同按钮上的buttonclicks并启动相应的js文件。我在applicationcontroller和每个文件中都有POST PUT和DELETE方法,但是我至少希望得到一个GET并从那里继续。因此,这是GET请求的JS文件,该文件正进行其余交换的整个客户端:

   var kapitelname = document.getElementsByClassName("titelanzeige")[0].value;



$.ajax({
    headers: {
        'Authorization': 'Basic ' + btoa("bank" + ":" + "bank")
    },
    url: "http://localhost:8080/Kategorie/Welt/Kapitel/" +kapitelname,

    type: 'GET',
    success: function(data) {
        $('.titelanzeige').html("");
        $('.inhaltsanzeige').html("");
        $('.titelanzeige').append(data.kapitelname);
        $('.inhaltsanzeige').append(data.inhalt);
    }
});

我尝试将Origin:添加到此,但是它没有被识别,只会出现一个错误。将类型更改为text或json并没有实现任何目的。因此,在为服务器和客户端实施了一系列解决方案之后,我仍然受到相同来源策略的阻碍,我的主要问题是如何检查这两个方面中的哪一个有问题,以便我知道该怎么做上。提前致谢。

1 个答案:

答案 0 :(得分:0)

仍然不确定如何测试哪一个不起作用,但我确实找到了解决方案。 我实施了2个更改,其中之一可能起到了作用:

我添加了

configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("*"));
    configuration.setAllowedHeaders(Arrays.asList("*"));

打包到WebConfig类,然后我更改了

<script src="allstar.js" defer></script>

<script src="allstar.js" crossorigin="anonymous" defer></script>

现在我CORS终于不再是问题了。所有这些都是基于之前提出的Stackoverflow问题,但是代码包含大约20个独立的答案代码,因此问题就没那么多了。