CORS
2024. 2. 24. 15:24ㆍSpring Boot
교차 출처 리로스 공유
Cross Origin Resource Sharing은
쉽게 말해 외부에서 내 서버의 리소스를 사용하는 것을 허가할 지에 대한 내용이다.

같은 https://localhost:5000에서 요청을 넣었기에 아무런 문제 없이 응답이 왔다

다른 곳에서 요청을 보내니 CORS policy 때문에 blocked 됬다고 에러가 났다
해결 방법은 Spring Security를 사용 중일 경우
http.cors(c -> c
.configurationSource(corsConfig)
);
filterchain에 위와 같이 설정을 추가하면 된다.
전체 코드는
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfigurationSource;
import com.example.demo.jwt.jwtAuthenticationFilter;
import com.example.demo.jwt.jwtAuthorizationFilter;
import com.example.demo.jwt.jwtProvider;
import com.example.demo.oauth.CustomOAuth2Service;
import com.example.demo.redis.redis_repository;
import com.example.demo.user.customAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true
)
public class SecurityConfig {
@Autowired
private CustomOAuth2Service customoAuth2Service;
@Autowired
private final jwtProvider tokenProvider;
@Qualifier("corsConfig")
@Autowired
CorsConfigurationSource corsConfig;
@Autowired
redis_repository repoR;
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors(c -> c
.configurationSource(corsConfig)
);
http.httpBasic((basic) -> basic.disable());
http.apply(new jwtDsl(tokenProvider));
http.apply(new sessionDsl());
http.logout((logout) -> logout
.logoutUrl("/user/logout/session")
.logoutSuccessUrl("/"));
http.sessionManagement((session) ->
session
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS));
http.csrf((csrf) -> csrf
.ignoringRequestMatchers(new AntPathRequestMatcher("/form/**")));
http.headers((headers) -> headers
.addHeaderWriter(new XFrameOptionsHeaderWriter(
XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)));
http.oauth2Login((oauth) -> oauth
.loginPage("/")
.userInfoEndpoint((userInfoEndpoint) -> userInfoEndpoint
.userService(customoAuth2Service)));
return http.build();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public class jwtDsl extends AbstractHttpConfigurer<jwtDsl, HttpSecurity> {
private final jwtProvider jwtProvider;
public jwtDsl(jwtProvider jwtProvider) {
this.jwtProvider = jwtProvider;
}
@Override
public void configure(HttpSecurity http) throws Exception {
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
jwtAuthenticationFilter filter = new jwtAuthenticationFilter(authenticationManager, jwtProvider);
filter.setFilterProcessesUrl("/user/login/jwt/auth");
http
.addFilter(new jwtAuthorizationFilter(authenticationManager, jwtProvider))
.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
}
}
public class sessionDsl extends AbstractHttpConfigurer<sessionDsl, HttpSecurity> {
@Override
public void configure(HttpSecurity http) throws Exception {
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
customAuthenticationFilter filter = new customAuthenticationFilter(authenticationManager, repoR);
filter.setFilterProcessesUrl("/user/login/session/auth");
http.
addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
}
}
}
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@Configuration
public class CorsConfig {
@Bean
@Qualifier("corsConfig")
public CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return source;
}
}
깔끔하게 정리하기 위해
굳이 CorsConfigurationSource를 따로 정의 했지만
그냥 SecurityConfig안에 정의해서 써도 된다.

'Spring Boot' 카테고리의 다른 글
| Authorization by Spring Security (0) | 2024.02.28 |
|---|---|
| Jpa 순환 참조 N + 1 문제 (0) | 2024.02.27 |
| Naver Login (0) | 2024.02.19 |
| Web Socket By STOMP (0) | 2024.02.19 |
| Redis Pub/Sub (0) | 2024.02.19 |