Skip to content

Commit 7e4f560

Browse files
authored
Merge pull request #242 from morib-in/feat#217
fix : 제대로된 로깅을 보기 위한 클래스 상속받아서 로깅 진행
2 parents 61c503f + 9c068e3 commit 7e4f560

File tree

3 files changed

+104
-18
lines changed

3 files changed

+104
-18
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package org.morib.server.global.config;
2+
3+
import jakarta.servlet.http.HttpServletRequest;
4+
import jakarta.servlet.http.HttpServletResponse;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
7+
import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository;
8+
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
9+
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
10+
11+
@Slf4j
12+
public class DebugOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> {
13+
14+
private final HttpSessionOAuth2AuthorizationRequestRepository delegate = new HttpSessionOAuth2AuthorizationRequestRepository();
15+
16+
@Override
17+
public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) {
18+
log.info("=== loadAuthorizationRequest DEBUG START ===");
19+
log.info("Request URI: {}", request.getRequestURI());
20+
log.info("Request Method: {}", request.getMethod());
21+
log.info("Session ID: {}", request.getSession(false) != null ? request.getSession(false).getId() : "NO SESSION");
22+
23+
// 1. State 파라미터 확인
24+
String stateParameter = request.getParameter(OAuth2ParameterNames.STATE);
25+
log.info("1. State parameter from request: {}", stateParameter);
26+
27+
if (stateParameter == null) {
28+
log.error("❌ State parameter is NULL - returning null");
29+
return null;
30+
}
31+
32+
// 2. 실제 delegate에서 Authorization Request 찾기
33+
OAuth2AuthorizationRequest authorizationRequest = delegate.loadAuthorizationRequest(request);
34+
log.info("2. Authorization request from session: {}", authorizationRequest != null ? "FOUND" : "NULL");
35+
36+
if (authorizationRequest == null) {
37+
log.error("❌ Authorization request NOT FOUND in session - returning null");
38+
return null;
39+
}
40+
41+
// 3. State 비교
42+
String sessionState = authorizationRequest.getState();
43+
log.info("3. State comparison:");
44+
log.info(" Request state: {}", stateParameter);
45+
log.info(" Session state: {}", sessionState);
46+
log.info(" States equal: {}", stateParameter.equals(sessionState));
47+
48+
boolean statesMatch = stateParameter.equals(sessionState);
49+
if (!statesMatch) {
50+
log.error("❌ State MISMATCH - returning null");
51+
log.error(" Request state length: {}", stateParameter.length());
52+
log.error(" Session state length: {}", sessionState.length());
53+
// 첫 50자만 비교 로깅
54+
log.error(" Request state (first 50): {}", stateParameter.length() > 50 ? stateParameter.substring(0, 50) + "..." : stateParameter);
55+
log.error(" Session state (first 50): {}", sessionState.length() > 50 ? sessionState.substring(0, 50) + "..." : sessionState);
56+
return null;
57+
}
58+
59+
log.info("✅ All checks passed - returning authorization request");
60+
return authorizationRequest;
61+
}
62+
63+
@Override
64+
public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, HttpServletResponse response) {
65+
log.info("=== saveAuthorizationRequest DEBUG ===");
66+
log.info("Session ID: {}", request.getSession(true).getId());
67+
log.info("State being saved: {}", authorizationRequest != null ? authorizationRequest.getState() : "NULL");
68+
log.info("Registration ID: {}", authorizationRequest != null ? authorizationRequest.getAttribute("registration_id") : "NULL");
69+
70+
delegate.saveAuthorizationRequest(authorizationRequest, request, response);
71+
log.info("✅ Authorization request saved successfully");
72+
}
73+
74+
@Override
75+
public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) {
76+
log.info("=== removeAuthorizationRequest DEBUG ===");
77+
OAuth2AuthorizationRequest result = delegate.removeAuthorizationRequest(request, response);
78+
log.info("Remove result: {}", result != null ? "SUCCESS" : "NULL");
79+
return result;
80+
}
81+
}

morib/src/main/java/org/morib/server/global/config/SecurityConfig.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
5858
oauth2.failureHandler(oAuth2LoginFailureHandler);
5959
oauth2.tokenEndpoint(tokenEndpointConfig -> tokenEndpointConfig.accessTokenResponseClient(accessTokenResponseClient(customRequestEntityConverter())));
6060
oauth2.userInfoEndpoint(user -> user.userService(customOAuth2UserService));
61-
oauth2.authorizationEndpoint(auth -> auth
62-
.authorizationRequestRepository(authorizationRequestRepository())
63-
.authorizationRequestResolver(customAuthorizationRequestResolver));
64-
61+
// oauth2.authorizationEndpoint(auth -> auth
62+
// .authorizationRequestResolver(customAuthorizationRequestResolver));
6563
});
6664

6765
http.authorizeHttpRequests((auth) -> auth
@@ -91,9 +89,4 @@ public JwtAuthenticationFilter jwtAuthenticationFilter() {
9189
return new JwtAuthenticationFilter(jwtService, userRepository, customJwtAuthenticationEntryPoint);
9290
}
9391

94-
@Bean
95-
public HttpSessionOAuth2AuthorizationRequestRepository authorizationRequestRepository() {
96-
return new HttpSessionOAuth2AuthorizationRequestRepository();
97-
}
98-
9992
}

morib/src/main/java/org/morib/server/global/oauth2/handler/OAuth2LoginSuccessHandler.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.morib.server.domain.user.infra.type.Role;
1717
import org.morib.server.global.common.SecretProperties;
1818
import org.morib.server.global.common.util.DataUtils;
19+
import org.morib.server.global.config.DebugOAuth2AuthorizationRequestRepository;
1920
import org.morib.server.global.exception.BusinessException;
2021
import org.morib.server.global.exception.NotFoundException;
2122
import org.morib.server.global.exception.UnauthorizedException;
@@ -60,7 +61,7 @@ public class OAuth2LoginSuccessHandler implements AuthenticationSuccessHandler
6061
private final UserManager userManager;
6162
private final ObjectMapper objectMapper = new ObjectMapper();
6263
private static final String IS_ONBOARDING_COMPLETED = "isOnboardingCompleted";
63-
private final HttpSessionOAuth2AuthorizationRequestRepository authorizationRequestRepository = new HttpSessionOAuth2AuthorizationRequestRepository();
64+
private final DebugOAuth2AuthorizationRequestRepository authorizationRequestRepository;
6465

6566

6667

@@ -98,14 +99,25 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
9899
log.warn("State parameter is missing or invalid. Cannot determine client type. Defaulting to 'web'.");
99100
} else {
100101
log.info("now in else phase");
101-
byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedStateFromRequest);
102-
String stateJson = new String(decodedBytes, StandardCharsets.UTF_8);
103-
Map<String, String> stateMap = objectMapper.readValue(stateJson, new TypeReference<Map<String, String>>() {});
104-
105-
log.info("now before clientType");
106-
clientType = stateMap.getOrDefault(STATE_CLIENT_TYPE_KEY, "web");
107-
String originalCsrfToken = stateMap.get(STATE_CSRF_KEY);
108-
log.info("Successfully validated state. Client Type: {}, Original CSRF: {}", clientType, originalCsrfToken);
102+
103+
// Apple은 원본 state 사용으로 JSON 파싱 불가 - 특별 처리
104+
CustomOAuth2User tempOAuth2User = (CustomOAuth2User) authentication.getPrincipal();
105+
String registrationId = tempOAuth2User.getRegistrationId();
106+
107+
if ("apple".equals(registrationId)) {
108+
log.info("Apple 로그인: 원본 state 사용, clientType을 web으로 기본 설정");
109+
clientType = "web"; // Apple은 기본적으로 web으로 처리
110+
} else {
111+
// 다른 provider는 기존 JSON 파싱 방식
112+
byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedStateFromRequest);
113+
String stateJson = new String(decodedBytes, StandardCharsets.UTF_8);
114+
Map<String, String> stateMap = objectMapper.readValue(stateJson, new TypeReference<Map<String, String>>() {});
115+
116+
log.info("now before clientType");
117+
clientType = stateMap.getOrDefault(STATE_CLIENT_TYPE_KEY, "web");
118+
String originalCsrfToken = stateMap.get(STATE_CSRF_KEY);
119+
log.info("Successfully validated state. Client Type: {}, Original CSRF: {}", clientType, originalCsrfToken);
120+
}
109121
}
110122

111123
CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal();

0 commit comments

Comments
 (0)