スタートアップアプリケーション:
@SpringBootApplication
@EnableZuulProxy
public class ZuulServer {
public static void main(String[] args) {
new SpringApplicationBuilder(ZuulServer.class).web(true).run(args);
}
}
私のYAMLファイルは次のとおりです:
server:
port:8080
spring:
application:
name: zuul
eureka:
client:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
zuul:
proxy:
route:
springapp: /springapp
Springappというマイクロサービスアプリケーション(ポート8081)があり、残りのサービスがあります。以下は私のクライアントUIアプリです:
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="js/libs/jquery/jquery.min.js" ></script>
</head>
<body>
<script type="text/javascript">
$.ajax({
url: 'http://localhost:8080/zuul/springapp/departments',
type: 'GET'
}).done(function (data) {
consoe.log(data);
document.write(data);
});
</script>
</body>
</html>
しかし、私は
XMLHttpRequest cannot load http://localhost:8080/zuul/springapp/departments. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8383' is therefore not allowed access.
このUI HTML5アプリは http:// localhost:8383/SimpleAPp/index.html にあります。 CORS、CORS、CORS ...助けてください。ところで http:// localhost:8080/zuul/springapp/departments は、ブラウザーのアドレスバーにあるときに想定されているjsonリストを返します。 spring.ioのブログ here は、zuulproxyがフィルターを処理するため、フィルターは必要ないと述べていますが、なぜ機能しないのかわかりません。
このコードを@EnableZuulProxyで注釈が付けられたクラスに追加すると、うまくいくはずです。
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final 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);
}
アプリケーションがhttp://localhost:8383
で実行されている場合は、http://localhost:8383
に対してのみAJAX呼び出しを行うことができます。 Zuulは変更せず、変更することもできません。
Zuulができることは、リクエストをマッピングすることです。 http://localhost:8383/zuul/
からhttp://localhost:8080/zuul/
へ。ただし、ブラウザはhttp://localhost:8383/zuul/springapp/departments
を呼び出す必要があり、そのマッピングを構成する必要があります。
Angular Webアプリが、ZuulとSpring Securityを備えたSpring Bootによって実装されたRESTfulサービスを消費するという問題がありました。
上記のソリューションはどれも機能しませんでした。問題はZuulではなく、Spring Securityにあることがわかりました。
公式ドキュメント( CORS with Spring Security )に記載されているように、Spring Securityを使用する場合は、CORSをSpring Securityの前に構成する必要があります。
最後に、グリニッシュネパール(以前の回答を参照)のソリューションを、機能するソリューションに統合することができました。
さらに苦労せずに、Spring SecurityとZuulでCORSを有効にするコードを次に示します。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//irrelevant for this problem
@Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//configure CORS -- uses a Bean by the name of corsConfigurationSource (see method below)
//CORS must be configured prior to Spring Security
.cors().and()
//configuring security - irrelevant for this problem
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
//irrelevant for this problem
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
//The CORS filter bean - Configures allowed CORS any (source) to any
//(api route and method) endpoint
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin(CorsConfiguration.ALL);
config.addAllowedHeaders(Collections.singletonList(CorsConfiguration.ALL));
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 source;
}
//configuring BA usernames and passwords - irrelevant for this problem
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
...
}
}
同じ問題があり、CorsFilter Beanを追加して修正しました
@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;
}
そしてzuulのプロパティをこのコードに追加します
zuul:
sensitiveHeaders:
ignored-headers: Access-Control-Allow-Credentials, Access-Control-Allow-Origin
あなたは問題の詳細を見つけることができます ここ
これは、ブラウザが共通のOriginポリシーに違反したことを通知するだけです( Wikipediaのエントリ を参照してください)。 CORSプリフライトチェックを実行して別のアドレスからリソースをロードしてもよいことをブラウザに教えるか(例:Filter
)、プロキシを介してHTMLをロードします(ヒント:後者の方が多いです)簡単でエラーが起こりにくい)。