Skip to content

Commit 3885a8d

Browse files
authored
Merge pull request #58 from team-fontory/develop
Add Logging on oAuth2
2 parents b05380c + 17633d5 commit 3885a8d

File tree

72 files changed

+505
-785
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+505
-785
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dependencies {
3131
// Spring Boot Starters:
3232
implementation 'org.springframework.boot:spring-boot-starter-web'
3333
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
34+
implementation 'org.springframework.boot:spring-boot-starter-validation'
3435

3536
// OAuth2
3637
implementation 'org.springframework.session:spring-session-data-redis'

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ services:
77
container_name: fontory-mariadb
88
environment:
99
MYSQL_ROOT_PASSWORD: rootPW
10-
MYSQL_DATRABASE: FONTORY
10+
MYSQL_DATABASE: FONTORY
1111
MYSQL_USER: fontory
1212
MYSQL_PASSWORD: fontoryPW
1313
ports:

src/main/java/org/fontory/fontorybe/FonToryBeApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
import org.springframework.context.annotation.Bean;
1111
import org.springframework.core.env.Environment;
1212
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
13+
import org.springframework.retry.annotation.EnableRetry;
1314
import org.springframework.scheduling.annotation.EnableAsync;
1415

1516
import lombok.extern.slf4j.Slf4j;
1617

1718
@Slf4j
1819
@EnableAsync
20+
@EnableRetry
1921
@EnableJpaAuditing
2022
@SpringBootApplication
2123
@EnableConfigurationProperties({JwtProperties.class, MemberDefaults.class})

src/main/java/org/fontory/fontorybe/authentication/adapter/inbound/CustomOauth2FailureHandler.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import jakarta.servlet.http.HttpServletRequest;
66
import jakarta.servlet.http.HttpServletResponse;
77
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
89
import org.springframework.security.core.AuthenticationException;
910
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
1011
import org.springframework.stereotype.Component;
@@ -13,6 +14,7 @@
1314
import java.util.HashMap;
1415
import java.util.Map;
1516

17+
@Slf4j
1618
@Component
1719
@RequiredArgsConstructor
1820
public class CustomOauth2FailureHandler implements AuthenticationFailureHandler {
@@ -22,8 +24,18 @@ public class CustomOauth2FailureHandler implements AuthenticationFailureHandler
2224
public void onAuthenticationFailure(HttpServletRequest request,
2325
HttpServletResponse response,
2426
AuthenticationException exception) throws IOException, ServletException {
27+
log.warn("OAuth2 authentication failed: errorMessage={}, exceptionType={}",
28+
exception.getMessage(), exception.getClass().getSimpleName());
29+
30+
String requestUrl = request.getRequestURL().toString();
31+
String queryString = request.getQueryString();
32+
log.debug("Failed OAuth2 request details: url={}, queryString={}", requestUrl, queryString);
33+
2534
Map<String, Object> attributes = new HashMap<>();
2635
attributes.put("message", "error occurred during authentication");
36+
37+
log.info("Sending OAuth2 authentication failure response: status={}", HttpServletResponse.SC_UNAUTHORIZED);
38+
2739
response.setContentType("application/json");
2840
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
2941
response.getWriter().write(objectMapper.writeValueAsString(attributes));

src/main/java/org/fontory/fontorybe/authentication/adapter/inbound/CustomOauth2SuccessHandler.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import jakarta.servlet.http.HttpServletRequest;
44
import jakarta.servlet.http.HttpServletResponse;
55
import lombok.RequiredArgsConstructor;
6+
import lombok.extern.slf4j.Slf4j;
67
import org.fontory.fontorybe.authentication.application.dto.ResponseCookies;
78
import org.fontory.fontorybe.authentication.application.AuthService;
89
import org.fontory.fontorybe.authentication.application.port.CookieUtils;
@@ -21,6 +22,7 @@
2122
import java.io.IOException;
2223
import java.util.Objects;
2324

25+
@Slf4j
2426
@Component
2527
@RequiredArgsConstructor
2628
public class CustomOauth2SuccessHandler implements AuthenticationSuccessHandler {
@@ -37,19 +39,39 @@ public class CustomOauth2SuccessHandler implements AuthenticationSuccessHandler
3739
public void onAuthenticationSuccess(HttpServletRequest request,
3840
HttpServletResponse response,
3941
Authentication authentication) throws IOException {
42+
log.info("OAuth2 authentication success handler triggered");
43+
4044
OAuth2User authUser = (OAuth2User) authentication.getPrincipal();
4145
Provide provide = authUser.getAttribute("provide");
4246
Objects.requireNonNull(provide, "OAuth2User must have 'provide' attribute");
47+
48+
log.info("Processing successful OAuth2 login: provideId={}, provider={}, email={}",
49+
provide.getId(), provide.getProvider(), provide.getEmail());
4350

4451
Member member = memberOnboardService.fetchOrCreateMember(provide);
52+
log.info("Member fetched/created: memberId={}, status={}",
53+
member.getId(), member.getStatus());
54+
4555
ResponseCookies cookies = authService.issueAuthCookies(member);
56+
log.debug("Auth cookies issued for member: memberId={}", member.getId());
57+
4658
cookieUtils.addCookies(response, cookies);
59+
log.debug("Auth cookies added to response: memberId={}", member.getId());
4760

48-
redirectStrategy.sendRedirect(request, response, buildRedirectUrl(member));
61+
String redirectUrl = buildRedirectUrl(member);
62+
log.info("Redirecting user after successful OAuth2 login: memberId={}, status={}, redirectUrl={}",
63+
member.getId(), member.getStatus(), redirectUrl);
64+
65+
redirectStrategy.sendRedirect(request, response, redirectUrl);
4966
}
5067

5168
private String buildRedirectUrl(Member member) {
5269
String path = (member.getStatus() == MemberStatus.ONBOARDING) ? signUpPath : authPath;
53-
return baseUrl + path;
70+
String redirectUrl = baseUrl + path;
71+
72+
log.debug("Building redirect URL: memberStatus={}, path={}, fullUrl={}",
73+
member.getStatus(), path, redirectUrl);
74+
75+
return redirectUrl;
5476
}
5577
}

src/main/java/org/fontory/fontorybe/authentication/adapter/inbound/CustomOauth2UserService.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.fontory.fontorybe.authentication.adapter.inbound;
22

33
import lombok.RequiredArgsConstructor;
4+
import lombok.extern.slf4j.Slf4j;
45
import org.fontory.fontorybe.authentication.domain.Auth2UserInfo;
56
import org.fontory.fontorybe.provide.domain.Provide;
67
import org.fontory.fontorybe.provide.infrastructure.entity.Provider;
@@ -22,6 +23,7 @@
2223

2324
import static org.fontory.fontorybe.authentication.domain.Auth2UserInfo.getOAuth2UserInfo;
2425

26+
@Slf4j
2527
@Service
2628
@RequiredArgsConstructor
2729
public class CustomOauth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
@@ -30,16 +32,26 @@ public class CustomOauth2UserService implements OAuth2UserService<OAuth2UserRequ
3032
@Override
3133
@Transactional
3234
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
35+
String registrationId = userRequest.getClientRegistration().getRegistrationId();
36+
log.info("OAuth2 login attempt: provider={}", registrationId);
37+
3338
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
3439
OAuth2User oAuth2User = delegate.loadUser(userRequest);
40+
log.debug("OAuth2 user loaded from provider: provider={}", registrationId);
3541

3642
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
3743
Provider provider = Provider.from(userRequest.getClientRegistration().getRegistrationId());
3844
Map<String, Object> attributes = new HashMap<>(oAuth2User.getAttributes());
3945
Auth2UserInfo oAuth2UserInfo = getOAuth2UserInfo(provider, attributes, userNameAttributeName);
46+
47+
log.info("OAuth2 user info extracted: provider={}, userIdentifier={}, email={}",
48+
provider, oAuth2UserInfo.getUserIdentifier(), oAuth2UserInfo.getEmail());
4049

4150
Provide provide = getProvide(oAuth2UserInfo);
4251
attributes.put("provide", provide);
52+
53+
log.info("OAuth2 authentication successful: provider={}, provideId={}",
54+
provider, provide.getId());
4355

4456
return new DefaultOAuth2User(
4557
Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")),
@@ -51,17 +63,28 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
5163
private Provide getProvide(Auth2UserInfo oAuth2UserInfo) {
5264
String userIdentifier = oAuth2UserInfo.getUserIdentifier();
5365
Provider provider = oAuth2UserInfo.getProvider();
66+
67+
log.debug("Looking up provide info: userIdentifier={}, provider={}", userIdentifier, provider);
5468

5569
Optional<Provide> oAuthInfo = provideRepository.findByOAuthInfo(userIdentifier, provider);
5670

5771
if (oAuthInfo.isEmpty() || oAuthInfo.get().getId() == null) {
72+
log.info("Creating new provide entry: userIdentifier={}, provider={}, email={}",
73+
userIdentifier, provider, oAuth2UserInfo.getEmail());
74+
5875
Provide provide = Provide.builder()
5976
.providedId(userIdentifier)
6077
.email(oAuth2UserInfo.getEmail())
6178
.provider(provider)
6279
.build();
63-
return provideRepository.save(provide);
80+
Provide savedProvide = provideRepository.save(provide);
81+
82+
log.info("New provide created: provideId={}, userIdentifier={}, provider={}",
83+
savedProvide.getId(), userIdentifier, provider);
84+
return savedProvide;
6485
} else {
86+
log.info("Existing provide found: provideId={}, userIdentifier={}, provider={}",
87+
oAuthInfo.get().getId(), userIdentifier, provider);
6588
return oAuthInfo.get();
6689
}
6790
}

src/main/java/org/fontory/fontorybe/authentication/adapter/outbound/JwtTokenProviderImpl.java

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
1212
import org.springframework.security.core.Authentication;
1313
import org.springframework.stereotype.Component;
14+
import lombok.extern.slf4j.Slf4j;
1415

1516
import javax.crypto.SecretKey;
1617
import java.util.Date;
1718

19+
@Slf4j
1820
@Component
1921
public class JwtTokenProviderImpl implements JwtTokenProvider {
2022

@@ -36,6 +38,8 @@ private SecretKey getSigningKey(String key) {
3638

3739
public JwtTokenProviderImpl(
3840
JwtProperties props) {
41+
log.info("Initializing JWT token provider");
42+
3943
this.accessSecretKey = getSigningKey(props.getAccessSecretKey());
4044
this.refreshSecretKey = getSigningKey(props.getRefreshSecretKey());
4145
this.provideSecretKey = getSigningKey(props.getProvideSecretKey());
@@ -46,75 +50,119 @@ public JwtTokenProviderImpl(
4650
this.provideJwtParser = Jwts.parserBuilder().setSigningKey(provideSecretKey).build();
4751
this.fontCreateJwtParser = Jwts.parserBuilder().setSigningKey(fontCreateSecretKey).build();
4852
this.props = props;
53+
54+
log.debug("JWT token provider initialized with token validities - access: {}ms, refresh: {}ms",
55+
props.getAccessTokenValidityMs(), props.getRefreshTokenValidityMs());
4956
}
5057

5158
public String generateTemporalProvideToken(String id) {
59+
log.debug("Generating temporal provide token for id: {}", id);
60+
5261
Date now = new Date();
5362
Date expiryDate = new Date(now.getTime() + props.getTempTokenValidityMs());
54-
return Jwts.builder()
63+
String token = Jwts.builder()
5564
.setSubject(String.valueOf(id))
5665
.setIssuedAt(now)
5766
.setExpiration(expiryDate)
5867
.signWith(this.provideSecretKey)
5968
.compact();
69+
70+
log.info("Temporal provide token generated: id={}, expiresAt={}", id, expiryDate);
71+
return token;
6072
}
6173

6274
public Long getProvideId(String token) {
75+
log.debug("Extracting provide ID from token");
76+
6377
Claims claims = provideJwtParser
6478
.parseClaimsJws(token)
6579
.getBody();
66-
return Long.valueOf(claims.getSubject());
80+
Long provideId = Long.valueOf(claims.getSubject());
81+
82+
log.debug("Provide ID extracted: {}", provideId);
83+
return provideId;
6784
}
6885

6986
public String generateAccessToken(UserPrincipal user) {
87+
log.debug("Generating access token for user: {}", user.getId());
88+
7089
Date now = new Date();
7190
Date expiryDate = new Date(now.getTime() + props.getAccessTokenValidityMs());
72-
return Jwts.builder()
91+
String token = Jwts.builder()
7392
.setSubject(String.valueOf(user.getId()))
7493
.setIssuedAt(now)
7594
.setExpiration(expiryDate)
7695
.signWith(this.accessSecretKey)
7796
.compact();
97+
98+
log.info("Access token generated: userId={}, expiresAt={}", user.getId(), expiryDate);
99+
return token;
78100
}
79101

80102
public String generateRefreshToken(UserPrincipal user) {
103+
log.debug("Generating refresh token for user: {}", user.getId());
104+
81105
Date now = new Date();
82106
Date expiryDate = new Date(now.getTime() + props.getRefreshTokenValidityMs());
83-
return Jwts.builder()
107+
String token = Jwts.builder()
84108
.setSubject(String.valueOf(user.getId()))
85109
.setIssuedAt(now)
86110
.setExpiration(expiryDate)
87111
.signWith(refreshSecretKey)
88112
.compact();
113+
114+
log.info("Refresh token generated: userId={}, expiresAt={}", user.getId(), expiryDate);
115+
return token;
89116
}
90117

91118
public Long getMemberIdFromAccessToken(String token) {
119+
log.debug("Extracting member ID from access token");
120+
92121
Claims claims = accessJwtParser
93122
.parseClaimsJws(token)
94123
.getBody();
95-
return Long.valueOf(claims.getSubject());
124+
Long memberId = Long.valueOf(claims.getSubject());
125+
126+
log.debug("Member ID extracted from access token: {}", memberId);
127+
return memberId;
96128
}
97129

98130
public Long getMemberIdFromRefreshToken(String token) {
131+
log.debug("Extracting member ID from refresh token");
132+
99133
Claims claims = refreshJwtParser
100134
.parseClaimsJws(token)
101135
.getBody();
102-
return Long.valueOf(claims.getSubject());
136+
Long memberId = Long.valueOf(claims.getSubject());
137+
138+
log.debug("Member ID extracted from refresh token: {}", memberId);
139+
return memberId;
103140
}
104141

105142
public Authentication getAuthenticationFromAccessToken(String token) {
143+
log.debug("Creating authentication from access token");
144+
106145
Claims claims = accessJwtParser
107146
.parseClaimsJws(token)
108147
.getBody();
109148
Long id = Long.valueOf(claims.getSubject());
110149
UserPrincipal principal = new UserPrincipal(id);
111-
return new UsernamePasswordAuthenticationToken(principal, token, principal.getAuthorities());
150+
Authentication auth = new UsernamePasswordAuthenticationToken(principal, token, principal.getAuthorities());
151+
152+
log.info("Authentication created from access token: userId={}, authorities={}",
153+
id, principal.getAuthorities());
154+
return auth;
112155
}
113156

114157
public String getFontCreateServer(String token) {
158+
log.debug("Validating font create server token");
159+
115160
Claims claims = fontCreateJwtParser
116161
.parseClaimsJws(token)
117162
.getBody();
118-
return claims.getSubject();
163+
String subject = claims.getSubject();
164+
165+
log.debug("Font create server token validated: subject={}", subject);
166+
return subject;
119167
}
120168
}

0 commit comments

Comments
 (0)