2016-05-30 6 views
6

私はスプリングブートを使用して簡単な休憩サービスを提供しています。 Angular 2で消費するには、oauth/token endpointでトークンを取得するときにCORS問題が発生しました。スプリングブートレストサービスオプション401 on oauth/token

Chromeのエラーメッセージは次のとおりです。

error message

zone.js:101 OPTIONS http://192.168.0.9:8080/api/oauth/token 
XMLHttpRequest cannot load http://192.168.0.9:8080/api/oauth/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401. 

関連のファイルは以下の通りです。

MyConfig.java

@Configuration 
public class MyConfig { 
    @Bean 
    public WebMvcConfigurer corsConfigurer() { 
     return new WebMvcConfigurerAdapter() { 
      @Override 
      public void addCorsMappings(CorsRegistry registry) { 
       registry.addMapping("**") 
         .allowedOrigins("*").allowedMethods("POST, GET, HEAD, OPTIONS") 
       .allowCredentials(true) 
       .allowedHeaders("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers") 
       .exposedHeaders("Access-Control-Allow-Origin,Access-Control-Allow-Credentials") 
       .maxAge(10); 
      } 
     }; 
    } 
} 

OAuth2ResourceServerConfig.java

@Configuration 
@EnableResourceServer 
class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter { 
    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http 
      .csrf().disable() 
      .anonymous() 
      .and() 
       .authorizeRequests() 
       .antMatchers(HttpMethod.OPTIONS,"**").permitAll() 
       .antMatchers("/authenticated/**").authenticated() 
       ; 
    } 

} 

私は、javaと春に新たなんです。私はOAuth2 - Status 401 on OPTIONS request while retrieving TOKENのような似たような質問を見つけましたが、私は実際に春のブートで動作させる方法を理解していません。

通常のレストコントローラのエンドポイントは正常に動作します。問題はoauth/tokenです。オプション要求は401の状態を返します。

春の起動時に作業コードを表示してください。ありがとう!あなたがここにあなたのプロジェクトに

@Component 
@Order(Ordered.HIGHEST_PRECEDENCE) 

public class SimpleCORSFilter implements Filter { 

@Override 
public void init(FilterConfig fc) throws ServletException { 
} 

@Override 
public void doFilter(ServletRequest req, ServletResponse resp, 
     FilterChain chain) throws IOException, ServletException { 
    HttpServletResponse response = (HttpServletResponse) resp; 
    HttpServletRequest request = (HttpServletRequest) req; 
    response.setHeader("Access-Control-Allow-Origin", "*"); 
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); 
    response.setHeader("Access-Control-Max-Age", "3600"); 
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN"); 

    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { 
     response.setStatus(HttpServletResponse.SC_OK); 
    } else { 
     chain.doFilter(req, resp); 
    } 

} 

@Override 
public void destroy() { 
} 

} 

答えて

9

は、ネイティブのSpring Frameworkのソリューションです:

@Bean 
public CorsFilter corsFilter(CorsConfiguration config) { 
    log.debug("Registering CORS filter"); 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    source.registerCorsConfiguration("/api/**", config); 
    source.registerCorsConfiguration("/v2/api-docs", config); 
    source.registerCorsConfiguration("/oauth/**", config); 
    return new CorsFilter(source); 
} 
+0

私はこの回答を他の投稿で見つけました。しかし、SpringBootでは、WebMvcConfigurerAdapterをフィルタではなく私のコードのように使用することを推奨しました。あなたは "OPTIONS"部分を除いて同様のコードを持っていることがわかります。だから私のファイルに同様の "OPTIONS"コードを追加することは可能でしょうか?ありがとう。 – weijun

+0

コードが機能します! :) – weijun

+1

ありがとうございます!!!!!私はこの問題で約4日間過ごした後、私の救いました!!! –

1

このCORSフィルターを追加することができます

1

あなたは春ブーツ+春のOAuthを使用している場合は、

@Order(Ordered.HIGHEST_PRECEDENCE) 
を追加する必要があります

とCORSフィルタ

@Configuration 
@Order(Ordered.HIGHEST_PRECEDENCE) 
public class CORSFilter implements Filter { 

    private FilterConfig config; 

    public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials"; 
    public static final String ORIGIN_NAME = "Access-Control-Allow-Origin"; 
    public static final String METHODS_NAME = "Access-Control-Allow-Methods"; 
    public static final String HEADERS_NAME = "Access-Control-Allow-Headers"; 
    public static final String MAX_AGE_NAME = "Access-Control-Max-Age"; 

    @Override 
    public void destroy() { 

    } 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse resp, 
         FilterChain chain) throws IOException, ServletException { 
     HttpServletResponse response = (HttpServletResponse) resp; 
     HttpServletRequest request = (HttpServletRequest) req; 
     response.setHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); 
     response.setHeader("Access-Control-Max-Age", "3600"); 
     response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN"); 

     if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { 
      response.setStatus(HttpServletResponse.SC_OK); 
     } else { 
      chain.doFilter(req, resp); 
     } 

    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
     config = filterConfig; 
    } 
}