更新:1年以上後を振り返って、私は他の誰かを助ける更新の希望を与えています。
Spring IO通常のユーザーがブラウザで処理できるリクエストにはCSRF保護を使用することをお勧めします。ブラウザ以外のクライアントが使用するサービスのみを作成する場合は、私のアプリはAPIであり、ブラウザで処理されるため、CSRF保護を無効にすることはアプローチではありません。
CSRFはデフォルトでSpring Bootで有効になっています。次のコードを追加してCSRFリポジトリとフィルターを追加し、CSRFトークンをhttp要求に追加する必要があります。 (ソリューションはここから来ます Invalid CSRF Token in POST request )
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/assets/**", "/templates/**", "/custom-fonts/**", "/api/profile/**", "/h2/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class); // Register csrf filter.
}
フィルターとCsrfTokenリポジトリ部分:
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
// Token is being added to the XSRF-TOKEN cookie.
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
2016年2月に元の質問
Spring 4でのSpring-boot RESTful APIのグローバルCORSサポートの有効化に取り組んでいます。
私は公式のSpring Boot Doc( https://spring.io/guides/gs/rest-service-cors/ )に従い、これをアプリケーションに追加しました:
public class SomeApiApplication {
public static void main(String[] args) {
SpringApplication.run(SomeApiApplication.class, args);
}
//Enable Global CORS support for the application
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.allowedHeaders("header1", "header2") //What is this for?
.allowCredentials(true);
}
};
}
}
GETのみが機能している理由がわかりません。残りのhttp呼び出しでは、「無効なCORSリクエスト」というエラーメッセージが表示されます。セットアップで何かが恋しいですか?私の設定が正しくない場合、GETも同様に機能しません。私は非常に混乱しています。
私は同じ問題を抱えていました-GETは機能しました。 POSTはしませんでした。CORSドメインで答えを探しましたが、最終的にはCSRF保護によるものであることがわかりました。解決するために、セキュリティ構成でCSRF保護を無効にしました。
@Configuration @EnableWebSecurity
public class SpringWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
**.csrf().disable()** //TODO: for production, must be reconfigured in order to disable only in specific cases. This line was added because without it, HTTP POST requests did not work.
.authorizeRequests()
.antMatchers("/api/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
あなたが何をしているのかを理解してください: https://docs.spring.io/spring-security/site/docs/current/reference/html/web-app-security.html#csrf
私は同様の問題を抱えていました、HEAD GETおよびPOST=は私のために働いていました。 addCorsMappings
=には allowedMethods
のデフォルト値があります。
このコードは私のために機能します:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("http://localhost:4200");
}
};
}
}
allowedOrigins
メソッドを.allowedOrigins("*")
に変更してみてください。 Postmanは拡張機能であり、別の「ホスト」で実行されます。
ただし、影響を必ず理解してください。 https://spring.io/understanding/CORS
同様の問題があり、問題を解決するにはコントローラーの@CrossOriginを削除する必要があることがわかりました。しかし、それがなぜ「無効なCORSリクエスト」を引き起こしているのかを理解することはできません。
私は同じ問題に直面し、私が見つけたものを調査した後、ブラウザは応答でAccess-Control-Allow-Originという名前のHTTPヘッダーを探します。
ブラウザはOPTION requestを送信して、PUTs、DELETEなどのメソッドが許可されているかどうかを調べます。要求されたメソッドがサーバー側から許可されている場合、ブラウザは実際の要求を行い、応答のAccess-Control-Allow-Originヘッダーに応じて応答を再度渡すかブロックします。 Spring Beanを追加するだけで、問題が解決します。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class RestConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}