web-dev-qa-db-ja.com

Spring Global CORS構成は機能しませんが、コントローラーレベルの構成は機能します

以下に示すWebMvcConfigurerAdapterを介してCORSをグローバルに構成しようとしています。テストするために、外部サービスをエミュレートするために作成したスモールノードアプリを介してAPIエンドポイントにアクセスしています。このアプローチを試みると、応答に正しいヘッダーが含まれず、失敗します

XMLHttpRequest cannot load http://localhost:8080/api/query/1121. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:333' is therefore not allowed access.

グローバル設定

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;

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/query/**")
                    .allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowCredentials(true);
        }
}

ただし、@CrossOriginアノテーションのように、適切なヘッダーで正常に応答するように動作します。

@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*")
@RestController
@RequestMapping(value = "/api/query", produces = MediaType.APPLICATION_JSON_VALUE)
public class QueryController {
   ......
}

生産する

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:333

グローバル設定を機能させるために何が欠けていますか(ここの指示に従ってください https://spring.io/blog/2015/06/08/cors-support-in-spring-framework )。コントローラーに注釈を付けるとうまくいくので、単純なものが欠けているように感じます。

26
Adam James

グローバルCORS構成が機能するためには、クライアントはOPTIONSリクエストにこれら2つのヘッダーを追加する必要があります。

Origin: http://Host.com
Access-Control-Request-Method: POST

ただし、@ CrossOrigin注釈には「Origin」ヘッダーのみが必要です。
クライアントはおそらく「Origin」ヘッダーを追加しますが、「Access-Control-Request-Method」が欠落しています..... @ CrossOriginでは機能しますが、グローバルでは機能しません。設定.

14
outdev

デフォルトではgetメソッドのみを受け入れるメソッドを宣言していません。 registry.allowedMethods("*");を試してください

4

この問題に記載されている正確な問題を経験した後、Spring Global CORS構成を機能させることができました。私は2つのことをしなければなりませんでした:

  1. allowCredentialsがtrueの場合、allowedOriginsを*にすることはできません。これはMozilla.orgで文書化されています

  2. Spring XMLからmvc:annotation-drivenを削除します。 XML構成と@EnableWebMvcの両方を持つことはできません。グローバルクラスは@EnableWebMvcがないと機能しないため、mvc:annotation-drivenを削除する必要があります。

2
user9124560

私はちょうどこのスレッドの解決策のどれも機能せず、まったく同じ問題を抱えています。私は次のことでそれを解決することができました:

新しい構成Bean:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilterConfiguration {

  @Bean
  public CorsFilter corsFilter() {
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      CorsConfiguration config = new CorsConfiguration();
      config.setAllowCredentials(true);
      config.addAllowedOrigin("*");
      config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
      config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
      source.registerCorsConfiguration("/**", config);
      return new CorsFilter(source);
  }
}

すべてのURLに新しいフィルターを追加するためのweb.xmlの変更:

<filter>
  <filter-name>corsFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>corsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

もちろん、cors configを適宜変更できます。

1
Tom

同様の問題に直面しました。WebMvcConfigurerAdapterをWebMvcConfigurationSupportに変更し、動作を開始しました。

これに加えて、xml構成ファイルで定義されたRequestMappingHandlerMappingをJava構成に移動しました。

1
Bharat Singh

マッピング定義に*がないと思います:

registry.addMapping("/api/query/**")

余分な*がないと、この構成は/api/query/1121要求パスにマップされません(ただし、/api/query/5で機能します)。

0
Brian Clozel

私は同じ問題に直面しており、maxAge属性を設定した後、すべてが正常に動作し始めました!

@Bean
public WebMvcConfigurer CORSConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                    .maxAge(-1)   // add maxAge
                    .allowCredentials(false);
        }
    };
}

CrossOrigin注釈をチェックすると、その属性にデフォルト値が割り当てられます

/**
 * <p>By default this is set to {@code 1800} seconds (30 minutes).
 */
long maxAge() default -1;
0
Jorge L. Morla

同様の問題が発生し、どのメソッドも機能しなかったようです(各コントローラーに@CrossOriginアノテーションを使用することを除く)。 Bharat Singh's 上記のソリューションとSpring Frameworkの内部のデバッグの後-を使用しました(Spring Boot 2.0.6 + Spring Framework 5.0.10):

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

/* (non-Javadoc)
 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
 */
@Override
protected void addCorsMappings(CorsRegistry registry) {
    //NOTE: servlet context set in "application.properties" is "/api" and request like "/api/session/login" resolves here to "/session/login"!
    registry.addMapping("/**")
        .allowedMethods("GET", "POST", "PUT", "DELETE")
        .allowedOrigins("*")
        .allowedHeaders("*")
        .allowCredentials(false);
    }
}

最初に"/api/**"マッピングを使用したとき、Spring内で構成されましたが、アプリケーションは"/api"コンテキストでデプロイされたため、"/api/session/login"のようなリクエストは"/session/login"に内部的にマッピングされ、そのようなマッピングはCORS構成が見つかりませんでした-注意してください!

0