import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.*; @Configuration @AutoConfigureBefore(SecurityConfig.class) public class MyMvcConfigurer implements WebMvcConfigurer { public void addCorsMappings(CorsRegistry registry){ LOGGER.info("跨域已设置"); registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }
セキュリティを統合する際に、セキュリティを使用するだけの場合には依然としてクロスドメインの問題が存在することがわかりました。上記の方法でフロント エンドとバック エンドを分離します。
@Configuration @AutoConfigureBefore(Swagger2Configuration.class) @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @Order(-1) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginProcessingUrl("/user/login") .loginPage("/singIn.html") .successHandler(moyuAuthenticationSuccessHandler) .failureHandler(moyuAuthenticationFailureHandler) .and() .apply(moyuSocialSecurityConfig) .and() .rememberMe() .tokenRepository(persistentTokenRepository()) .tokenValiditySeconds(3600*24*7) .userDetailsService(userDetailsService) .and() .authorizeRequests() .antMatchers("/user/login","/login","/singIn.html","**","/**").permitAll() .anyRequest() .authenticated() .and() .cors() .and() .csrf().disable(); } }
.and() .cors()//新加入 .and() .csrf().disable();
最近のプロジェクトはフロントエンドとバックエンドの分離フレームワークを採用していますが、フロントエンドとバックエンドのインターフェイスがサイトにデプロイされていないため、クロスドメインの問題が発生します。クロスドメインであるため、ここでは詳細には立ち入らず、ソリューションについてのみ説明します。
具体的なコードは次のとおりです:
@Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); final CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); return new CorsFilter(urlBasedCorsConfigurationSource); }
構成が完了したら、を呼び出してエラー 401 を報告しても、まだ機能しません。ネットで情報を確認したところ、クロスドメインリクエストが2回行われることが分かりました。具体的なプロセスを次の図に示します。
クロスドメイン リクエストごとに、実際のリクエストがバックエンドに到達する前に、ブラウザはまずプリフライト リクエストを開始します。リクエストメソッドはサーバーにクエリするためのオプションです。クロスドメインリクエストを受け入れるかどうか、特定のパラメータは次のとおりです:
#ただし、リクエストには Cookie と自己を含めることはできません。 -定義されたヘッダー。
Spring セキュリティがプロジェクトに導入されて以来、私が使用したトークン配信方法は、ヘッダーの authorization フィールドを使用することでした。この方法で、Spring Security を利用してプリフライト リクエストをインターセプトしたところ、それが機能することがわかりました。トークンが保持されていないため、エラー 401 が報告され、許可されていません。
@Override public void configure(HttpSecurity http) throws Exception { ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests(); registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();//让Spring security放行所有preflight request }
これは再試行すると修正されますが、クロスドメインをサポートするようにバックエンドを直接構成すると、2 つのリクエストが発生します。もう 1 つの方法は、Nginx を使用してリクエストを転送することです。
以上がSpringBoot+Spring Securityでクロスドメインが実現できない問題の解決方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。