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); } }
Security를 통합할 때 위의 방법만 사용하여 앞과 뒤를 분리하는 경우에도 여전히 크로스 도메인 문제가 있음을 발견했습니다.
@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 오류를 보고하지만 여전히 발생합니다. 작동하지 않습니다. 온라인으로 정보를 확인해보니 도메인 간 요청이 두 번 이루어진다는 것을 알게 되었습니다. 구체적인 프로세스는 아래 그림에 나와 있습니다.
각 도메인 간 요청에 대해 실제 요청이 백엔드에 도달하기 전에 브라우저는 먼저 실행 전 요청을 시작하여 서버에 요청합니다. 교차 도메인 요청을 수락합니다. 구체적인 매개변수는 다음과 같습니다. 그림:
그러나 이 요청은 쿠키와 자체 정의 헤더를 전달할 수 없습니다.
프로젝트에 Spring 보안이 도입된 이후로 제가 사용한 토큰 전달 방법은 헤더의 인증 필드를 사용하는 것이었습니다. 이런 식으로 Spring Security를 사용하여 실행 전 요청을 가로채고 토큰을 전달하지 않는 것을 발견했습니다. 인증이 없음을 나타내는 오류 401이 보고됩니다.
Spring 보안이 실행 전 요청을 확인하지 않도록 할 수 있습니다.
@Override public void configure(HttpSecurity http) throws Exception { ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests(); registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();//让Spring security放行所有preflight request }
다시 시도한 후 수정되었지만 크로스 도메인을 지원하도록 백엔드를 직접 구성하면 두 개의 요청이 발생합니다. 또 다른 방법은 Nginx를 사용하여 요청을 전달하는 것입니다.
위 내용은 SpringBoot+Spring Security가 도메인 간을 달성할 수 없는 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!