From f2c1b88348a24526543138205ef8190490b19beb Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 18 Jan 2024 06:20:36 +0900 Subject: [PATCH 1/7] =?UTF-8?q?fix:=20OAuthLoginController=20@RestControll?= =?UTF-8?q?er=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80(=EB=82=98=EB=8A=94=20=EB=B0=94=EB=B3=B4..)=20?= =?UTF-8?q?=EB=B0=8F=20favicon=20=EA=B4=80=EB=A0=A8=20=EC=9E=84=EC=8B=9C?= =?UTF-8?q?=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/OAuthLoginController.java | 16 ++++++++++++---- src/main/resources/favicon.ico | 0 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/favicon.ico diff --git a/src/main/java/net/teumteum/auth/controller/OAuthLoginController.java b/src/main/java/net/teumteum/auth/controller/OAuthLoginController.java index 782080be..12900600 100644 --- a/src/main/java/net/teumteum/auth/controller/OAuthLoginController.java +++ b/src/main/java/net/teumteum/auth/controller/OAuthLoginController.java @@ -9,8 +9,10 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; @Slf4j +@RestController @RequiredArgsConstructor public class OAuthLoginController { @@ -18,9 +20,15 @@ public class OAuthLoginController { @GetMapping("/logins/callbacks/{provider}") @ResponseStatus(HttpStatus.OK) - public TokenResponse oAuthLogin( - @PathVariable String provider, - @RequestParam String code) { - return oAuthService.oAuthLogin(provider, code); + public TokenResponse oAuthLogin(@PathVariable String provider, + @RequestParam String code, + @RequestParam String state) { + return oAuthService.oAuthLogin(provider, code, state); + } + + @GetMapping("/favicon.ico") + @ResponseStatus(HttpStatus.OK) + public Void favicon() { + return null; } } diff --git a/src/main/resources/favicon.ico b/src/main/resources/favicon.ico new file mode 100644 index 00000000..e69de29b From 0581102b2860a97364840eabeff8b21093fa2d3f Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 18 Jan 2024 06:21:10 +0900 Subject: [PATCH 2/7] =?UTF-8?q?refactor=20:=20=EC=84=A4=EC=A0=95=20yml=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-auth.yml | 2 +- src/main/resources/application-datasource.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-auth.yml b/src/main/resources/application-auth.yml index da4b5d77..204305b8 100644 --- a/src/main/resources/application-auth.yml +++ b/src/main/resources/application-auth.yml @@ -18,7 +18,7 @@ spring: naver: client-id: ${NAVER_CLIENT_ID} - client-secret: ${NAVER_CLIENT_ID} + client-secret: ${NAVER_CLIENT_SECRET} redirect-uri: ${NAVER_REDIRECT_URI} authorization-grant-type: authorization_code scope: diff --git a/src/main/resources/application-datasource.yml b/src/main/resources/application-datasource.yml index c3305ef8..a0e139df 100644 --- a/src/main/resources/application-datasource.yml +++ b/src/main/resources/application-datasource.yml @@ -6,7 +6,7 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: + url: ${DATABASE_URL} username: ${DATABASE_USERNAME} password: ${DATABASE_PASSWORD} hikari: @@ -14,7 +14,7 @@ spring: maximum-pool-size: 80 flyway: - url: + url: ${DATABASE_URL} user: ${DATABASE_USERNAME} password: ${DATABASE_PASSWORD} baseline-on-migrate: true From bbab74f0a798e7061ad17b5d0cb955cf1ac0e721 Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 18 Jan 2024 06:21:34 +0900 Subject: [PATCH 3/7] =?UTF-8?q?refactor=20:=20SecurityConfig=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81=20(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/teumteum/core/security/SecurityConfig.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/teumteum/core/security/SecurityConfig.java b/src/main/java/net/teumteum/core/security/SecurityConfig.java index fc437297..9c2f8094 100644 --- a/src/main/java/net/teumteum/core/security/SecurityConfig.java +++ b/src/main/java/net/teumteum/core/security/SecurityConfig.java @@ -28,8 +28,8 @@ @RequiredArgsConstructor public class SecurityConfig { - private static final String[] PATTERNS = {"/css/**", "/images/**", "/js/**", "/favicon.ico", "/h2-console/**", - "/logins/**"}; + private static final String[] PATTERNS = {"/css/**", "/images/**", "/js/**", "/favicon.ico/**", "/h2-console/**", + "/logins/**", "/auth/**"}; private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; private final JwtAccessDeniedHandler accessDeniedHandler; @@ -38,14 +38,18 @@ public class SecurityConfig { @Bean public WebSecurityCustomizer webSecurityCustomizer() { return web -> web.ignoring() - .requestMatchers("/css/**", "/js/**", "/img/**", "/favicon.ico", "/error"); + .requestMatchers("/css/**", "/js/**", + "/favicon.ico", "/resources/**" + + ); } + @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf(AbstractHttpConfigurer::disable).cors(cors -> cors.configurationSource(corsConfigurationSource())) - .authorizeHttpRequests(request -> request.requestMatchers("/auth/**", "/logins/**").permitAll() - .requestMatchers(HttpMethod.POST, "/users/registers").permitAll().requestMatchers(PATTERNS).permitAll() + .authorizeHttpRequests(request -> request.requestMatchers(PATTERNS).permitAll() + .requestMatchers(HttpMethod.POST, "/users/registers").permitAll() .anyRequest().authenticated()).httpBasic(AbstractHttpConfigurer::disable) .formLogin(AbstractHttpConfigurer::disable) .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(STATELESS)) From 132a003bfab5cc087d8bc3a20a536088bb81bd19 Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 18 Jan 2024 06:22:02 +0900 Subject: [PATCH 4/7] =?UTF-8?q?refactor=20:=20=EA=B8=B0=ED=83=80=20OAuth?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/domain/KakaoOAuthUserInfo.java | 2 +- .../net/teumteum/auth/domain/OAuthToken.java | 22 +---------- .../teumteum/auth/service/OAuthService.java | 38 ++++++++++++------- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/main/java/net/teumteum/auth/domain/KakaoOAuthUserInfo.java b/src/main/java/net/teumteum/auth/domain/KakaoOAuthUserInfo.java index 497e1712..ddcdf915 100644 --- a/src/main/java/net/teumteum/auth/domain/KakaoOAuthUserInfo.java +++ b/src/main/java/net/teumteum/auth/domain/KakaoOAuthUserInfo.java @@ -10,6 +10,6 @@ public KakaoOAuthUserInfo(Map attributes) { @Override public String getOAuthId() { - return (String) attributes.get("id"); + return String.valueOf(attributes.get("id")); } } diff --git a/src/main/java/net/teumteum/auth/domain/OAuthToken.java b/src/main/java/net/teumteum/auth/domain/OAuthToken.java index fc856490..0712cd4e 100644 --- a/src/main/java/net/teumteum/auth/domain/OAuthToken.java +++ b/src/main/java/net/teumteum/auth/domain/OAuthToken.java @@ -4,29 +4,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; public record OAuthToken( - @JsonProperty("token_type") - String tokenType, @JsonProperty("access_token") String accessToken, String scope, - - @JsonProperty("expires_in") - Integer expiresIn + @JsonProperty("token_type") + String tokenType ) { - public String getTokenType() { - return this.tokenType; - } - - public String getAccessToken() { - return this.accessToken; - } - - public String getScope() { - return this.scope; - } - - public Integer getExpiresIn() { - return this.expiresIn; - } } diff --git a/src/main/java/net/teumteum/auth/service/OAuthService.java b/src/main/java/net/teumteum/auth/service/OAuthService.java index 410f2e57..17529651 100644 --- a/src/main/java/net/teumteum/auth/service/OAuthService.java +++ b/src/main/java/net/teumteum/auth/service/OAuthService.java @@ -5,6 +5,7 @@ import static net.teumteum.core.security.Authenticated.카카오; import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED; +import java.net.URLEncoder; import java.util.Collections; import java.util.Map; import java.util.Optional; @@ -41,11 +42,11 @@ public class OAuthService { private final UserConnector userConnector; - public TokenResponse oAuthLogin(String registrationId, String code) { + public TokenResponse oAuthLogin(String registrationId, String code, String state) { ClientRegistration clientRegistration = inMemoryClientRegistrationRepository.findByRegistrationId( registrationId); Authenticated authenticated = getAuthenticated(clientRegistration.getRegistrationId()); - OAuthUserInfo oAuthUserInfo = getOAuthUserInfo(clientRegistration, authenticated, code); + OAuthUserInfo oAuthUserInfo = getOAuthUserInfo(clientRegistration, authenticated, code, state); return makeResponse(oAuthUserInfo, authenticated); } @@ -57,8 +58,9 @@ private Authenticated getAuthenticated(String registrationId) { } private OAuthUserInfo getOAuthUserInfo(ClientRegistration clientRegistration, Authenticated authenticated, - String code) { - Map oAuthAttribute = getOAuthAttribute(clientRegistration, getToken(clientRegistration, code)); + String code, String state) { + Map oAuthAttribute = getOAuthAttribute(clientRegistration, + getToken(clientRegistration, code, state)); if (authenticated == 네이버) { return new NaverOAuthUserInfo(oAuthAttribute); } @@ -73,31 +75,39 @@ private TokenResponse makeResponse(OAuthUserInfo oAuthUserInfo, Authenticated au .orElseGet(() -> new TokenResponse(oauthId)); } + private OAuthToken getToken(ClientRegistration clientRegistration, String code, String state) { + return WebClient.create().post() + .uri(clientRegistration.getProviderDetails().getTokenUri()) + .headers(header -> { + header.setContentType(APPLICATION_FORM_URLENCODED); + header.setAcceptCharset(Collections.singletonList(UTF_8)); + }).bodyValue(tokenRequest(clientRegistration, code, state)) + .retrieve() + .bodyToMono(OAuthToken.class).block(); + } + private Map getOAuthAttribute(ClientRegistration clientRegistration, OAuthToken oAuthToken) { - return WebClient.create().get().uri(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUri()) - .headers(header -> header.setBearerAuth(oAuthToken.getAccessToken())).retrieve() + return WebClient.create().get() + .uri(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUri()) + .headers(header -> header.setBearerAuth(oAuthToken.accessToken())).retrieve() .bodyToMono(new ParameterizedTypeReference>() { }).block(); } - private OAuthToken getToken(ClientRegistration clientRegistration, String code) { - return WebClient.create().post().uri(clientRegistration.getProviderDetails().getTokenUri()).headers(header -> { - header.setContentType(APPLICATION_FORM_URLENCODED); - header.setAcceptCharset(Collections.singletonList(UTF_8)); - }).bodyValue(tokenRequest(clientRegistration, code)).retrieve().bodyToMono(OAuthToken.class).block(); - } private Optional getUser(String oauthId, Authenticated authenticated) { return this.userConnector.findByAuthenticatedAndOAuthId(authenticated, oauthId); } - private MultiValueMap tokenRequest(ClientRegistration clientRegistration, String code) { + private MultiValueMap tokenRequest(ClientRegistration clientRegistration, String code, + String state) { MultiValueMap formData = new LinkedMultiValueMap<>(); formData.add("code", code); - formData.add("grant_type", "authorization_code"); + formData.add("grant_type", clientRegistration.getAuthorizationGrantType().getValue()); formData.add("redirect_uri", clientRegistration.getRedirectUri()); formData.add("client_secret", clientRegistration.getClientSecret()); formData.add("client_id", clientRegistration.getClientId()); + formData.add("state", URLEncoder.encode(state, UTF_8)); return formData; } } From e51ce77a8937ada30bdb71a0c15bcb900744d65d Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 18 Jan 2024 06:43:17 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor=20:=20Cors=20=ED=97=88=EC=9A=A9=20?= =?UTF-8?q?=EC=A3=BC=EC=86=8C=20=EC=9E=84=EC=8B=9C=20=EC=A0=84=EB=B6=80=20?= =?UTF-8?q?=ED=97=88=EC=9A=A9=20(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/net/teumteum/core/security/SecurityConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/teumteum/core/security/SecurityConfig.java b/src/main/java/net/teumteum/core/security/SecurityConfig.java index 9c2f8094..d90f25ba 100644 --- a/src/main/java/net/teumteum/core/security/SecurityConfig.java +++ b/src/main/java/net/teumteum/core/security/SecurityConfig.java @@ -64,8 +64,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); - config.addAllowedOrigin("http://localhost:3000"); - config.addAllowedOrigin("https://api.teum.org"); + config.addAllowedOrigin("*"); + config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")); config.addExposedHeader("Authorization"); From 690f05d2f0fbeb95e5d5e62ce8e908b04c2fa3f1 Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 18 Jan 2024 06:46:24 +0900 Subject: [PATCH 6/7] =?UTF-8?q?fix=20:=20SonarCloud=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/net/teumteum/core/security/SecurityConfig.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/teumteum/core/security/SecurityConfig.java b/src/main/java/net/teumteum/core/security/SecurityConfig.java index d90f25ba..46da1052 100644 --- a/src/main/java/net/teumteum/core/security/SecurityConfig.java +++ b/src/main/java/net/teumteum/core/security/SecurityConfig.java @@ -65,7 +65,6 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); - config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")); config.addExposedHeader("Authorization"); From fbd057d7c79c3b66f5135e69988b549d319c2636 Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 18 Jan 2024 06:54:24 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix=20:=20SonarCloud=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/net/teumteum/core/security/SecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/teumteum/core/security/SecurityConfig.java b/src/main/java/net/teumteum/core/security/SecurityConfig.java index 46da1052..17d77fe6 100644 --- a/src/main/java/net/teumteum/core/security/SecurityConfig.java +++ b/src/main/java/net/teumteum/core/security/SecurityConfig.java @@ -64,7 +64,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); - config.addAllowedOrigin("*"); + config.addAllowedOrigin("http://localhost:3000"); config.addAllowedHeader("*"); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")); config.addExposedHeader("Authorization");