2016-10-12 4 views
2

私は仕事ができない非常に簡単な例があります。スプリングブートデータレスト+ OPTIONS/DELETEのCORSが正しく有効化されていません

自分のデータベースとリポジトリをモデル化したドメインがあります。

public interface MyTestRepository extends CrudRepository<MyTest, Integer> { 
} 

私はhttp://resttesttest.com/を使ってテストしました。 GETメソッドについては、問題なくJSON REST情報を返します。

私はエンドポイントhttp://localhost:8080/mytest/1を照会でき、id = 1の情報をデータベースから取得できます。

ただし、DELETEオプションを使用しようとすると問題が発生します。私はhttp://localhost:8080/mytest/1でDELETEを実行した場合、私は、アクセス制御チェックを通過しないプリフライトリクエストに

応答を得る:いいえ 「アクセス制御 - 許可 - 起源」ヘッダが要求さ たリソース上に存在しています。したがって、発信元 '​​'は許可されません。 応答はHTTPステータスコード403を持っていました。

私は最初に以下を試しましたが、Spring-data-Restを使用しているため使用できないことがわかりました。 https://jira.spring.io/browse/DATAREST-573

@Override 
public void addCorsMappings(CorsRegistry registry) { 
    registry.addMapping("/**") 
     .allowedOrigins("*") 
     .allowedMethods("*") 
     .allowedHeaders("*") 
     .allowCredentials(true).maxAge(3600); 
} 

私はこれを見つけ出し、これを見つけました。

How to configure CORS in a Spring Boot + Spring Security application?

だから、私はまた、このスレッドを見つけ

@Bean 
public FilterRegistrationBean corsFilter() { 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    CorsConfiguration config = new CorsConfiguration(); 
    config.setAllowCredentials(true); 
    config.addAllowedOrigin("*"); 
    config.addAllowedHeader("*"); 
    config.addAllowedMethod("*"); 
    source.registerCorsConfiguration("/**", config); 
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); 
    bean.setOrder(0); 
    return bean; 
} 

を追加しました。

Spring Data Rest and Cors

と同様に、次のコードを試みたが、運。

@Bean 
public FilterRegistrationBean corsFilter() { 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    CorsConfiguration config = new CorsConfiguration(); 
    config.setAllowCredentials(true); 
    config.addAllowedOrigin("*"); 
    config.addAllowedHeader("*"); 
    config.addAllowedMethod("OPTIONS"); 
    config.addAllowedMethod("HEAD"); 
    config.addAllowedMethod("GET"); 
    config.addAllowedMethod("PUT"); 
    config.addAllowedMethod("POST"); 
    config.addAllowedMethod("DELETE"); 
    config.addAllowedMethod("PATCH"); 
    source.registerCorsConfiguration("/**", config); 
    // return new CorsFilter(source); 
    final FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); 
    bean.setOrder(0); 
    return bean; 
} 

私はすべてのすべてが合格するのが賢明CORS、しかし私はまだありません「*」私が持っているにもかかわらず、「アクセス制御が-起源許可」になっておくことができべきかテストするためにキャッチを追加しました。

この時点で、プリフライト要求がアクセス制御チェックをパスしない理由について、私は何も分かりません。

curlは削除を発行しても問題ありません。

編集:

正確な解決策が見つかりました。私は私が持っているものとこの方法の違いについては分かりませんが、これはうまくいくようです。

import org.springframework.stereotype.Component; 

import javax.servlet.*; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 

/** 
* Note this is a very simple CORS filter that is wide open. 
* This would need to be locked down. 
* Source: https://stackoverflow.com/questions/39565438/no-access-control-allow-origin-error-with-spring-restful-hosted-in-pivotal-web 
*/ 
@Component 
public class CORSFilter implements Filter { 

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletResponse response = (HttpServletResponse) res; 
     response.setHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); 
     response.setHeader("Access-Control-Max-Age", "3600"); 
     response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
     chain.doFilter(req, res); 
    } 

    public void init(FilterConfig filterConfig) {} 

    public void destroy() {} 

} 

答えて

1

は、これは私が許す限り、すべてのCORSサーブレットフィルタを使用するものである:以下の構成は、春データ休息ベースのアプリケーションで私の作品

public class PermissiveCORSFilter implements Filter { 

    private static final Logger LOGGER = LoggerFactory.getLogger(PermissiveCORSFilter.class); 
    private static final Pattern PATTERN = Pattern.compile("^[a-zA-Z0-9 ,-_]*$"); 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletResponse response = (HttpServletResponse) res; 
     HttpServletRequest request = (HttpServletRequest) req; 

     String origin; 
     String credentialFlag; 
     if (request.getHeader("Origin") == null) { 
      origin = "*"; 
      credentialFlag = "false"; 
     } else { 
      origin = request.getHeader("Origin"); 
      credentialFlag = "true"; 
     } 

     // need to do origin.toString() to avoid findbugs error about response splitting   
     response.addHeader("Access-Control-Allow-Origin", origin.toString()); 
     response.setHeader("Access-Control-Allow-Credentials", credentialFlag); 
     if ("OPTIONS".equals(request.getMethod())) { 
      LOGGER.info("Received OPTIONS request from origin:" + request.getHeader("Origin")); 
      response.setHeader("Access-Control-Allow-Methods", "GET,POST,HEAD,OPTIONS,PUT,DELETE"); 
      response.setHeader("Access-Control-Max-Age", "3600"); 
      String headers = StringUtils.trimToEmpty(request.getHeader("Access-Control-Request-Headers")); 
      if (!PATTERN.matcher(headers).matches()) { 
       throw new ServletException("Invalid value provided for 'Access-Control-Request-Headers' header"); 
      } 
      response.setHeader("Access-Control-Allow-Headers", headers); // allow any headers 
     } 
     chain.doFilter(req, res); 
    } 

    @Override 
    public void init(FilterConfig filterConfig) { 
     // Do nothing 
    } 

    @Override 
    public void destroy() { 
     // Do nothing 
    } 
+0

ありがとうございますが、私の春に使用して以来、私のOPのバグに基づいていますデータREST –

+0

大丈夫、それは興味深い..私たちはspring mvc + springデータを使用しており、その角のWebクライアントから呼び出されたときにそのフィルタは正常に動作するようです。 – Pete

+0

自動生成されたリポジトリを使用していますか?例えばリポジトリ(){}?テストするために@CrossOrigin(originins = "*")とマークしたクラスは、この問題がないようです。 –

2

。重要な点は、セキュリティフィルタチェーンが起動する前にフィルタが登録されていることです。

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 
{ 
    @Override 
    public void configure(HttpSecurity http) throws Exception 
    { 
    http.addFilterBefore(corsFilter(), ChannelProcessingFilter.class); 
    } 

    @Bean 
    protected Filter corsFilter() 
    { 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 

    CorsConfiguration config = new CorsConfiguration(); 
    config.setAllowCredentials(true); 
    config.addAllowedOrigin("*"); 
    config.addAllowedHeader("*"); 
    config.addAllowedMethod("OPTIONS"); 
    config.addAllowedMethod("HEAD"); 
    config.addAllowedMethod("GET"); 
    config.addAllowedMethod("PUT"); 
    config.addAllowedMethod("POST"); 
    config.addAllowedMethod("DELETE"); 
    config.addAllowedMethod("PATCH"); 
    config.addExposedHeader("Location"); 

    source.registerCorsConfiguration("/**", config); 

    return new CorsFilter(source); 
    } 
} 
+0

ありがとうございます。私はそれを直接私のSpring Appにコピーして貼り付け、その他の@Configurationクラスは無効にしてインポートを追加しましたが、同じエラーが残っています。あなたはスプリングブートデータレストを使用していますか?もしそうなら、自動的にRESTエンドポイントを生成するリポジトリクラスを使用していますか? –

関連する問題