스프링 부트 보안 CORS
봄 보안 URL의 CORS 필터에 문제가 있습니다.설정되지 않다Access-Control-Allow-Origin
스프링 초(로그인/로그아웃)에 속하거나 스프링 보안에 의해 필터링된 URL의 기타 노출된 헤더.
설정은 다음과 같습니다.
CORS:
@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(WebMvcConfigurer bean 사용):
처음에 사용한 CORS 설정은 Spring Boot에서 수행하는 적절한 방법이 아닙니다.를 등록해야 합니다.WebMvcConfigurer
콩. 여기를 참고하세요.
스프링 부트 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를 도입하면 보안 설정에 CORS를 등록해야 합니다.Spring Security는 기존 CORS 구성을 선택할 수 있을 만큼 스마트합니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and()
....
옵션 2(Cors Configuration Source bean 사용):
첫 번째 옵션은 기존 애플리케이션에 Spring Security를 추가하는 것입니다.처음부터 Spring Security를 추가할 경우 Spring Security Docs에서 설명하는 방법에는 Cors Configuration Source bean을 추가합니다.
@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;
}
}
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')");
}
}
이것은 매우 깨끗하며 추가 구성이 필요하지 않습니다.모든 옵션을 유효하게 하는 위치에 별표를 전달합니다(setAllowed에서 한 것처럼).헤더).
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().configurationSource(request -> {
var cors = new CorsConfiguration();
cors.setAllowedOrigins(List.of("http://localhost:4200", "http://127.0.0.1:80", "http://example.com"));
cors.setAllowedMethods(List.of("GET","POST", "PUT", "DELETE", "OPTIONS"));
cors.setAllowedHeaders(List.of("*"));
return cors;
}).and()...
}
}
나는 가지고 있다React
기반 웹 클라이언트 및 백엔드 REST API가 실행되고 있습니다.Spring Boot
버전 1.5.2
신속한 대응이 필요했습니다.CORS
에서 실행되고 있는 클라이언트로부터의 모든 컨트롤러 루트 요구에서localhost:8080
보안 설정 내에 단순히 1개의 IP 주소를 추가했을 뿐입니다.@Bean
타입의FilterRegistrationBean
쉽게 할 수 있었어요.
코드는 다음과 같습니다.
@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 문서는 여기에서 참조할 수 있습니다.
비슷한 문제가 있었는데, 리액트의 프런트엔드에서 http://localhost:3000으로 실행되는 요청을 SpringBoot의 백엔드에서 http://localhost:8080으로 실행하려고 했습니다.두 가지 오류가 있었습니다.
접근통제 허용원점
이 문제는 Rest Controller에 추가함으로써 매우 쉽게 해결되었습니다.
@CrossOrigin(origins = ["http://localhost:3000"])
이것을 수정한 후, 다음의 에러가 표시되기 시작했습니다.응답의 'Access-Control-Allow-Credentials' 헤더 값은 'true'여야 합니다.
액세스 제어 허가 자격 정보
이것은, 다음의 2개의 방법으로 해결할 수 있습니다.
" " "
allowCredentials = "true"
크로스 오리진@CrossOrigin(origins = ["http://localhost:3000"], allowCredentials = "true")
프런트 엔드 요청에서 가져오기 자격 증명 옵션 변경.기본적으로 다음과 같이 fetch 호출을 수행해야 합니다.
fetch('http://localhost:8080/your/api', { credentials: 'same-origin' })
도움이 되길 바랍니다 =)
현재 보안이 설정되어 있는 경우 OPTIONS 요청은 기본적으로 차단됩니다.
bean을 추가하기만 하면 비행 전 요청이 올바르게 처리됩니다.
@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
빠른 로컬 개발을 위해 필요한 경우 컨트롤러에 이 주석을 추가하십시오.(필요에 따라 코스 변경 원점)
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
요격기로도 이 작업을 수행할 수 있습니다.
다음 예외를 사용하여 요청 라이프사이클을 종료합니다.
@ResponseStatus (
value = HttpStatus.NO_CONTENT
)
public class CorsException extends RuntimeException
{
}
그런 다음 인터셉터에서 모든 OPTIONS 요청의 헤더를 설정하고 예외를 슬로우합니다.
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("/**");
}
}
2020년에도 같은 문제로 고민하는 사람이 있다면.이게 날 위해 한 일이야이 앱은 학습용 앱이기 때문에 모든 것을 활성화했습니다.
CorsFilter 클래스:
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Content-Length, X-Requested-With");
chain.doFilter(req, res);
}
@Override
public void destroy() {
}
}
다음으로 Web Security Configurer Adapter를 확장하는 클래스의 헤더 셋업을 실시합니다.
@Configuration
@EnableWebSecurity
public class SpringSecurityConfigurationBasicAuth extends WebSecurityConfigurerAdapter {
@Bean
CorsFilter corsFilter() {
CorsFilter filter = new CorsFilter();
return filter;
}
protected void configure(HttpSecurity http) throws Exception {
System.out.println("Im configuring it");
(
(HttpSecurity)
(
(HttpSecurity)
(
(ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)
http
.headers().addHeaderWriter(
new StaticHeadersWriter("Access-Control-Allow-Origin", "*")).and()
.addFilterBefore(corsFilter(), SessionManagementFilter.class)
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS,"/**").permitAll()
.anyRequest()
).authenticated().and()
).formLogin().and()
).httpBasic();
}
}
아래 구성으로 시도했더니 작동했어요!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().configurationSource(configurationSource()).and()
.requiresChannel()
.anyRequest()
.requiresSecure();
}
private CorsConfigurationSource configurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
config.addAllowedHeader("X-Requested-With");
config.addAllowedHeader("Content-Type");
config.addAllowedMethod(HttpMethod.POST);
source.registerCorsConfiguration("/**", config);
return source;
}
}
언급URL : https://stackoverflow.com/questions/40286549/spring-boot-security-cors
'itsource' 카테고리의 다른 글
스프링 부트 REST 응용 프로그램에서 Firebase를 사용하는 방법 (0) | 2023.03.18 |
---|---|
데이터베이스에 어레이 저장: JSON vs. serialized 어레이 (0) | 2023.03.18 |
jQuery looping .each() JSON 키/값이 작동하지 않습니다. (0) | 2023.03.18 |
jQuery를 사용하지 않고 node.js에서 JSON 결합 또는 병합 (0) | 2023.03.18 |
JSON의 용도와 용도는 무엇입니까? (0) | 2023.03.18 |