[SPRING] 봄 부팅 보안 CORS
SPRING봄 부팅 보안 CORS
스프링 보안 URL에 CORS 필터 문제가 있습니다. Springsec (로그인 / 로그 아웃)에 속하거나 URL 보안에 의해 필터링 된 URL에 Access-Control-Allow-Origin 및 기타 노출 된 헤더를 설정하지 않습니다.
다음은 구성입니다.
코스 :
@Configuration
@EnableWebMvc
public class MyWebMvcConfig extends WebMvcConfigurerAdapter {
********some irrelevant configs************
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
.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")
.allowCredentials(true).maxAge(3600);
}
}
보안:
@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and()
.formLogin()
.successHandler(ajaxSuccessHandler)
.failureHandler(ajaxFailureHandler)
.loginProcessingUrl("/authentication")
.passwordParameter("password")
.usernameParameter("username")
.and()
.logout()
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/authentication").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/admin/*").access("hasRole('ROLE_ADMIN')")
.antMatchers("/user/*").access("hasRole('ROLE_USER')");
}
}
그래서, 보안에 귀를 기울이지 않은 URL을 요청하면 CORS 헤더가 설정됩니다. 봄 보안 URL - 설정되지 않았습니다.
봄 부팅 1.4.1
해결법
-
==============================
1.CorsRegistry를 사용하는 대신 자신의 CorsFilter를 작성하여 보안 구성에 추가 할 수 있습니다.
CorsRegistry를 사용하는 대신 자신의 CorsFilter를 작성하여 보안 구성에 추가 할 수 있습니다.
사용자 정의 CorsFilter 클래스 :
public class CorsFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; HttpServletRequest request= (HttpServletRequest) servletRequest; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT,OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "*"); response.setHeader("Access-Control-Allow-Credentials", true); response.setHeader("Access-Control-Max-Age", 180); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
보안 구성 클래스 :
@Configuration @EnableWebSecurity public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter { @Bean CorsFilter corsFilter() { CorsFilter filter = new CorsFilter(); return filter; } @Override protected void configure(HttpSecurity http) throws Exception { http .addFilterBefore(corsFilter(), SessionManagementFilter.class) //adds your custom CorsFilter .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and() .formLogin() .successHandler(ajaxSuccessHandler) .failureHandler(ajaxFailureHandler) .loginProcessingUrl("/authentication") .passwordParameter("password") .usernameParameter("username") .and() .logout() .deleteCookies("JSESSIONID") .invalidateHttpSession(true) .logoutUrl("/logout") .logoutSuccessUrl("/") .and() .csrf().disable() .anonymous().disable() .authorizeRequests() .antMatchers("/authentication").permitAll() .antMatchers("/oauth/token").permitAll() .antMatchers("/admin/*").access("hasRole('ROLE_ADMIN')") .antMatchers("/user/*").access("hasRole('ROLE_USER')"); } }
-
==============================
2.시작한 CORS 구성은 Spring Boot로 올바른 방법이 아닙니다. WebMvcConfigurer bean을 등록해야합니다. 여기를 참조하십시오.
시작한 CORS 구성은 Spring Boot로 올바른 방법이 아닙니다. WebMvcConfigurer bean을 등록해야합니다. 여기를 참조하십시오.
봄 부팅 CORS 설정 예 :
@Configuration @Profile("dev") public class DevConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("http://localhost:4200"); } }; } }
이렇게하면 기본 (보안 시작 없음) 스프링 부트 응용 프로그램에 대한 CORS 구성이 제공됩니다. CORS 지원은 Spring Security와 독립적으로 존재한다는 점에 유의하십시오.
Spring Security를 소개하고 나면 보안 설정으로 CORS를 등록해야합니다. 스프링 시큐리티는 기존의 CORS 구성을 선택하기에 충분히 똑똑합니다.
@Override protected void configure(HttpSecurity http) throws Exception { http .cors().and() ....
필자가 설명한 첫 번째 옵션은 실제로 Spring Security를 기존 애플리케이션에 추가하는 관점에서입니다. Spring Security Docfiles에서 설명하는 방법에는 CorsConfigurationSource 빈을 추가하는 것이 포함된다.
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http // by default uses a Bean by the name of corsConfigurationSource .cors().and() ... } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("https://example.com")); configuration.setAllowedMethods(Arrays.asList("GET","POST")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
-
==============================
3.저는 React 기반의 웹 클라이언트를 가지고 있고, 백엔드 REST API는 Spring Boot Ver 1.5.2를 실행하고 있습니다.
저는 React 기반의 웹 클라이언트를 가지고 있고, 백엔드 REST API는 Spring Boot Ver 1.5.2를 실행하고 있습니다.
localhost : 8080에서 실행중인 클라이언트의 모든 컨트롤러 경로 요청에서 CORS를 신속하게 활성화하려고했습니다. 내 보안 구성 내에서 FilterRegistrationBean 유형의 @Bean을 추가하고 쉽게 작동하도록했습니다.
다음은 코드입니다.
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class AuthConfiguration extends WebSecurityConfigurerAdapter { .... .... @Bean public FilterRegistrationBean corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin(corsAllowedOrigin); // @Value: http://localhost:8080 config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean; } @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // **permit OPTIONS call to all** .... } .... .... }
여기에서 Spring Boot 문서를 참조 할 수 있습니다.
-
==============================
4.인터셉터를 사용하여이 작업을 수행 할 수도 있습니다.
인터셉터를 사용하여이 작업을 수행 할 수도 있습니다.
예외를 사용하여 요청의 수명주기를 종료하는지 확인하십시오.
@ResponseStatus ( value = HttpStatus.NO_CONTENT ) public class CorsException extends RuntimeException { }
그런 다음 인터셉터에서 모든 OPTIONS 요청에 대한 헤더를 설정하고 예외를 throw합니다.
public class CorsMiddleware extends HandlerInterceptorAdapter { @Override public boolean preHandle ( HttpServletRequest request, HttpServletResponse response, Object handler ) throws Exception { if (request.getMethod().equals("OPTIONS")) { response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Credentials", "true"); response.addHeader("Access-Control-Allow-Methods","GET, POST, PUT, OPTIONS, DELETE"); response.addHeader("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,Authorization,If-Modified-Since,Cache-Control,Content-Type"); response.addHeader("Access-Control-Max-Age", "3600"); response.addHeader("charset", "utf-8"); throw new CorsException(); } return super.preHandle(request, response, handler); } }
마지막으로 모든 경로에 인터셉터를 적용합니다.
@Configuration public class MiddlewareConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(new CorsMiddleware()) .addPathPatterns("/**"); } }
-
==============================
5.빠른 지역 개발을 위해 필요한 경우이 주석을 컨트롤러에 추가하십시오. (필요에 따라 오프 코스 변경 출처)
빠른 지역 개발을 위해 필요한 경우이 주석을 컨트롤러에 추가하십시오. (필요에 따라 오프 코스 변경 출처)
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
-
==============================
6.보안이 사용 가능하면 OPTIONS 요청은 기본적으로 차단됩니다.
보안이 사용 가능하면 OPTIONS 요청은 기본적으로 차단됩니다.
추가 빈을 추가하면 프리 플라이트 요청이 올바르게 처리됩니다.
@Bean public IgnoredRequestCustomizer optionsIgnoredRequestsCustomizer() { return configurer -> { List<RequestMatcher> matchers = new ArrayList<>(); matchers.add(new AntPathRequestMatcher("/**", "OPTIONS")); configurer.requestMatchers(new OrRequestMatcher(matchers)); }; }
응용 프로그램에 따라 잠재적 악용으로 열릴 수 있습니다.
더 나은 솔루션을위한 열린 문제 : https://github.com/spring-projects/spring-security/issues/4448
-
==============================
7.방금 비슷한 문제가 있었는데, http : // localhost : 3000에서 실행중인 React에서 프론트 엔드의 요청을 http : // localhost : 8080에서 실행중인 SpringBoot의 백엔드로 실행하려고했습니다. 나는 두 가지 오류가 있었다 :
방금 비슷한 문제가 있었는데, http : // localhost : 3000에서 실행중인 React에서 프론트 엔드의 요청을 http : // localhost : 8080에서 실행중인 SpringBoot의 백엔드로 실행하려고했습니다. 나는 두 가지 오류가 있었다 :
액세스 제어 허용 원점
이것을 RestController에 추가하여 매우 쉽게 해결했습니다.
@CrossOrigin(origins = ["http://localhost:3000"])
이 문제를 해결 한 후에이 오류가 발생하기 시작했습니다. 응답의 'Access-Control-Allow-Credentials'헤더의 값은 ''이어야하며 'true'여야합니다.
액세스 제어 허용 자격 증명
이 방법은 두 가지 방법으로 해결할 수 있습니다.
const response = fetch ( 'http : // localhost : 8080 / your / api', {신임장 : '동일 출처'})를 기다린다.
희망이 도움이 =)
from https://stackoverflow.com/questions/40286549/spring-boot-security-cors by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring-Boot : 최대 연결 수와 같은 JDBC 풀 속성을 어떻게 설정합니까? (0) | 2018.12.22 |
---|---|
[SPRING] 스프링 데이터에서 PagedResourcesAssembler를 올바르게 사용하는 방법은 무엇입니까? (0) | 2018.12.21 |
[SPRING] Apache Commons Logging의 런타임 검색 알고리즘 문제는 무엇입니까? (0) | 2018.12.21 |
[SPRING] 주입 및 리소스 및 자동 연결 주석 (0) | 2018.12.21 |
[SPRING] Spring-MVC : "컨텍스트"와 "네임 스페이스"란 무엇입니까? (0) | 2018.12.21 |