From 16aa78cda9e2019b1beb29c52c4ab76df53acec3 Mon Sep 17 00:00:00 2001 From: heejjinkim <06.hjhj.12@gmail.com> Date: Tue, 3 Sep 2024 18:19:58 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20config=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feign, redis, security 설정 related to: #11 --- .../global/config/FeignClientConfig.java | 10 ++++ .../_119/wepro/global/config/RedisConfig.java | 60 +++++++++++++++++++ .../wepro/global/config/SecurityConfig.java | 48 +++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 src/main/java/com/_119/wepro/global/config/FeignClientConfig.java create mode 100644 src/main/java/com/_119/wepro/global/config/RedisConfig.java create mode 100644 src/main/java/com/_119/wepro/global/config/SecurityConfig.java diff --git a/src/main/java/com/_119/wepro/global/config/FeignClientConfig.java b/src/main/java/com/_119/wepro/global/config/FeignClientConfig.java new file mode 100644 index 0000000..e546da3 --- /dev/null +++ b/src/main/java/com/_119/wepro/global/config/FeignClientConfig.java @@ -0,0 +1,10 @@ +package com._119.wepro.global.config; + +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableFeignClients(basePackages = "com._119.wepro.global.security.client") +public class FeignClientConfig { + +} \ No newline at end of file diff --git a/src/main/java/com/_119/wepro/global/config/RedisConfig.java b/src/main/java/com/_119/wepro/global/config/RedisConfig.java new file mode 100644 index 0000000..e34aa5c --- /dev/null +++ b/src/main/java/com/_119/wepro/global/config/RedisConfig.java @@ -0,0 +1,60 @@ +package com._119.wepro.global.config; + +import java.time.Duration; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.CacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +@EnableRedisRepositories +public class RedisConfig { + + @Value("${spring.data.redis.host}") + private String host; + + @Value("${spring.data.redis.port}") + private int port; + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(host, port); + } + + @Bean + public CacheManager oidcCacheManager(RedisConnectionFactory cf) { + RedisCacheConfiguration redisCacheConfiguration = + RedisCacheConfiguration.defaultCacheConfig() + .serializeKeysWith( + RedisSerializationContext.SerializationPair.fromSerializer( + new StringRedisSerializer())) + .serializeValuesWith( + RedisSerializationContext.SerializationPair.fromSerializer( + new GenericJackson2JsonRedisSerializer())) + .entryTtl(Duration.ofDays(7L)); + + return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(cf) + .cacheDefaults(redisCacheConfiguration) + .build(); + } + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory()); + + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + + return redisTemplate; + } +} diff --git a/src/main/java/com/_119/wepro/global/config/SecurityConfig.java b/src/main/java/com/_119/wepro/global/config/SecurityConfig.java new file mode 100644 index 0000000..cf0533e --- /dev/null +++ b/src/main/java/com/_119/wepro/global/config/SecurityConfig.java @@ -0,0 +1,48 @@ +package com._119.wepro.global.config; + +import com._119.wepro.global.security.jwt.JwtTokenProvider; +import com._119.wepro.global.security.jwt.JwtTokenFilter; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +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.configuration.WebSecurityCustomizer; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfig { + + private final JwtTokenProvider jwtTokenProvider; + + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { // security를 적용하지 않을 리소스 + return web -> web.ignoring() + .requestMatchers("/css/**", "/images/**", "/js/**", "/lib/**") + .requestMatchers("/", "/swagger-ui-custom.html", "/api-docs/**", "/swagger-ui/**", "swagger-ui.html", "/v3/api-docs/**") + .requestMatchers("/error", "/favicon.ico") + .requestMatchers("/auth/**", "/login/oauth2/code/**", "/login"); + } + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(AbstractHttpConfigurer::disable) + .headers(header -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) + .sessionManagement(c -> c.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests(request -> request + .requestMatchers("/", "/auth/**", "/login/oauth2/code/**", "/login").permitAll() + .requestMatchers(HttpMethod.OPTIONS).permitAll() + .anyRequest().authenticated() + ) + .addFilterBefore(new JwtTokenFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class); + return http.build(); + } +}