Skip to content

Commit 391e089

Browse files
Fix: Update EasyPlusOauth2AuthenticationException to include the cause in the stack trace.
This enhancement makes debugging easier. It was an oversight.
1 parent cde9e5f commit 391e089

File tree

8 files changed

+31
-74
lines changed

8 files changed

+31
-74
lines changed

client/src/main/java/com/patternhelloworld/securityhelper/oauth2/client/config/securityimpl/introspector/CustomResourceServerTokenIntrospector.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.springframework.security.oauth2.server.resource.introspection.SpringOpaqueTokenIntrospector;
1717
import org.springframework.stereotype.Component;
1818

19-
import java.util.Arrays;
2019
import java.util.Map;
2120

2221
/*
@@ -70,7 +69,7 @@ public OAuth2AuthenticatedPrincipal introspect(String token) {
7069
try {
7170
return delegate.introspect(token);
7271
} catch (Exception e) {
73-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_FAILURE)).message(e.getMessage() + Arrays.toString(e.getStackTrace())).build());
72+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_FAILURE)).message(e.getMessage()).build(), e);
7473
}
7574
}
7675
case "database" -> {
@@ -92,7 +91,7 @@ public OAuth2AuthenticatedPrincipal introspect(String token) {
9291

9392
return (OAuth2AuthenticatedPrincipal) conditionalDetailsService.loadUserByUsername(username, clientId);
9493
}catch (Exception e) {
95-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_FAILURE)).message(e.getMessage() + Arrays.toString(e.getStackTrace())).build());
94+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_FAILURE)).message(e.getMessage()).build(), e);
9695
}
9796
}
9897
default -> throw new EasyPlusOauth2AuthenticationException("Wrong introspection type : " + introspectionType);

client/src/main/resources/application.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ spring.mvc.view.suffix=.html
8989
# Drawbacks: Lacks real-time authorization updates.
9090
#
9191
# [WARNING] api: Certain test cases are currently failing due to issues with the specified introspection URI calls.
92-
patternhelloworld.securityhelper.oauth2.introspection.type=database
92+
patternhelloworld.securityhelper.oauth2.introspection.type=api
9393
patternhelloworld.securityhelper.oauth2.introspection.uri=http://localhost:8370/oauth2/introspect
9494
patternhelloworld.securityhelper.oauth2.introspection.client-id=client_customer
9595
patternhelloworld.securityhelper.oauth2.introspection.client-secret=12345

lib/src/main/java/io/github/patternhelloworld/securityhelper/oauth2/api/config/security/introspector/DefaultResourceServerTokenIntrospector.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public OAuth2AuthenticatedPrincipal introspect(String token) {
6262
try {
6363
return delegate.introspect(token);
6464
} catch (Exception e) {
65-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_ERROR)).message(e.getMessage() + Arrays.toString(e.getStackTrace())).build());
65+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_ERROR)).message(e.getMessage()).build(), e);
6666
}
6767
}
6868
case "database" -> {
@@ -84,7 +84,7 @@ public OAuth2AuthenticatedPrincipal introspect(String token) {
8484

8585
return (OAuth2AuthenticatedPrincipal) conditionalDetailsService.loadUserByUsername(username, clientId);
8686
}catch (Exception e) {
87-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_ERROR)).message(e.getMessage() + Arrays.toString(e.getStackTrace())).build());
87+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_TOKEN_ERROR)).message(e.getMessage()).build(), e);
8888
}
8989
}
9090
default -> throw new EasyPlusOauth2AuthenticationException("Wrong introspection type : " + introspectionType);

lib/src/main/java/io/github/patternhelloworld/securityhelper/oauth2/api/config/security/provider/auth/endpoint/PasswordAuthenticationProvider.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ public Authentication authenticate(Authentication authentication)
5959
UserDetails userDetails;
6060

6161
/*
62-
* To only get authorization_code, NOT access_token or refresh_token
63-
* */
62+
* To only get authorization_code, NOT access_token or refresh_token
63+
* */
6464
if (((String) easyPlusGrantAuthenticationToken.getAdditionalParameters().get("grant_type")).equals(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())) {
6565

6666
userDetails = conditionalDetailsService.loadUserByUsername((String) easyPlusGrantAuthenticationToken.getAdditionalParameters().get("username"), clientId);
@@ -88,7 +88,7 @@ public Authentication authenticate(Authentication authentication)
8888
else if (((String) easyPlusGrantAuthenticationToken.getAdditionalParameters().get("grant_type")).equals(OAuth2ParameterNames.CODE)) {
8989

9090
OAuth2Authorization oAuth2Authorization = oAuth2AuthorizationService.findByAuthorizationCode((String) easyPlusGrantAuthenticationToken.getAdditionalParameters().get("code"));
91-
if(oAuth2Authorization == null){
91+
if (oAuth2Authorization == null) {
9292
throw new EasyPlusOauth2AuthenticationException("authorization code not found");
9393
}
9494

@@ -136,12 +136,12 @@ else if (((String) easyPlusGrantAuthenticationToken.getAdditionalParameters().ge
136136
} else {
137137
throw new EasyPlusOauth2AuthenticationException();
138138
}
139-
}catch (UsernameNotFoundException e){
140-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(e.getMessage()).build());
141-
}catch (EasyPlusOauth2AuthenticationException e){
139+
} catch (UsernameNotFoundException e) {
140+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(e.getMessage()).build(), e);
141+
} catch (EasyPlusOauth2AuthenticationException e) {
142142
throw e;
143-
} catch (Exception e){
144-
throw e;
143+
} catch (Exception e) {
144+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_LOGIN_ERROR)).build(), e);
145145
}
146146

147147
}

lib/src/main/java/io/github/patternhelloworld/securityhelper/oauth2/api/config/security/response/error/dto/EasyPlusErrorMessages.java

+1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ public class EasyPlusErrorMessages {
1717
private String userMessage;
1818
private Map<String, String> userValidationMessage;
1919
private UserDetails userDetails;
20+
private String errorCode;
2021

2122
}

lib/src/main/java/io/github/patternhelloworld/securityhelper/oauth2/api/config/security/response/error/exception/EasyPlusOauth2AuthenticationException.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.response.error.dto.EasyPlusErrorMessages;
66
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
7+
import org.springframework.security.oauth2.core.OAuth2Error;
78

89
/*
9-
* Only OAuth2AuthenticationException is allowed to be tossed.
10+
* Only OAuth2AuthenticationException is allowed to be tossed according to "spring-authorization-server".
1011
* */
1112
public class EasyPlusOauth2AuthenticationException extends OAuth2AuthenticationException {
1213
protected EasyPlusErrorMessages easyPlusErrorMessages;
@@ -20,9 +21,16 @@ public EasyPlusOauth2AuthenticationException(String message){
2021
}
2122

2223
public EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages easyPlusErrorMessages){
23-
super(easyPlusErrorMessages.getMessage() == null ? "default" : easyPlusErrorMessages.getMessage());
24+
super(new OAuth2Error(easyPlusErrorMessages.getErrorCode() == null ? "default" : easyPlusErrorMessages.getErrorCode()), easyPlusErrorMessages.getMessage() == null ? "default" : easyPlusErrorMessages.getMessage());
2425
this.easyPlusErrorMessages = easyPlusErrorMessages;
2526
}
27+
28+
public EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages easyPlusErrorMessages, Throwable cause) {
29+
super(new OAuth2Error(easyPlusErrorMessages.getErrorCode() == null ? "default" : easyPlusErrorMessages.getErrorCode()),
30+
easyPlusErrorMessages.getMessage() == null ? "default" : easyPlusErrorMessages.getMessage(), cause);
31+
this.easyPlusErrorMessages = easyPlusErrorMessages;
32+
}
33+
2634
public EasyPlusErrorMessages getErrorMessages() {
2735
return easyPlusErrorMessages;
2836
}

lib/src/main/java/io/github/patternhelloworld/securityhelper/oauth2/api/config/security/server/EasyPlusJwtConfig.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class EasyPlusJwtConfig {
3232
private String algorithm;
3333

3434
@Bean
35-
JwtDecoder jwtDecoder() {
35+
public JwtDecoder jwtDecoder() {
3636
byte[] keyBytes = Base64.getDecoder().decode(jwtSecret);
3737
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, algorithm);
3838
return NimbusJwtDecoder.withSecretKey(secretKeySpec).build();

lib/src/main/java/io/github/patternhelloworld/securityhelper/oauth2/api/domain/traditionaloauth/service/TraditionalOauthService.java

+6-57
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package io.github.patternhelloworld.securityhelper.oauth2.api.domain.traditionaloauth.service;
22

33
import io.github.patternhelloworld.securityhelper.oauth2.api.config.logger.EasyPlusSecurityLogConfig;
4-
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.response.error.dto.EasyPlusErrorMessages;
5-
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.response.error.exception.EasyPlusOauth2AuthenticationException;
6-
74
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.message.DefaultSecurityUserExceptionMessage;
85
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.message.ISecurityUserExceptionMessageService;
6+
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.response.error.dto.EasyPlusErrorMessages;
7+
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.response.error.exception.EasyPlusOauth2AuthenticationException;
98
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.serivce.CommonOAuth2AuthorizationSaver;
109
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.serivce.DefaultOauth2AuthenticationHashCheckService;
1110
import io.github.patternhelloworld.securityhelper.oauth2.api.config.security.serivce.persistence.authorization.OAuth2AuthorizationServiceImpl;
@@ -22,9 +21,7 @@
2221
import org.springframework.security.core.userdetails.UsernameNotFoundException;
2322
import org.springframework.security.oauth2.core.AuthorizationGrantType;
2423
import org.springframework.security.oauth2.core.OAuth2AccessToken;
25-
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
2624
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
27-
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode;
2825
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
2926
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
3027
import org.springframework.stereotype.Service;
@@ -104,11 +101,11 @@ public SpringSecurityTraditionalOauthDTO.TokenResponse createAccessToken(SpringS
104101
String.join(" ", registeredClient.getScopes()));
105102

106103
} catch (UsernameNotFoundException e) {
107-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(e.getMessage()).build());
104+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(e.getMessage()).build(), e);
108105
} catch (EasyPlusOauth2AuthenticationException e) {
109106
throw e;
110107
} catch (Exception e) {
111-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_LOGIN_ERROR)).build());
108+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_LOGIN_ERROR)).build(), e);
112109
}
113110
}
114111

@@ -145,60 +142,12 @@ public SpringSecurityTraditionalOauthDTO.TokenResponse refreshAccessToken(Spring
145142
refreshTokenRemainingSeconds,
146143
String.join(" ", registeredClient.getScopes()));
147144

148-
}catch (UsernameNotFoundException e){
149-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(e.getMessage()).build());
150-
}catch (EasyPlusOauth2AuthenticationException e){
151-
throw e;
152-
} catch (Exception e){
153-
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_LOGIN_ERROR)).build());
154-
}
155-
}
156-
157-
158-
public SpringSecurityTraditionalOauthDTO.AuthorizationCodeResponse createAuthorizationCode(SpringSecurityTraditionalOauthDTO.AuthorizationCodeRequest authorizationCodeRequest,
159-
String authorizationHeader) throws EasyPlusOauth2AuthenticationException {
160-
try {
161-
162-
BasicTokenResolver.BasicCredentials basicCredentials = BasicTokenResolver.parse(authorizationHeader)
163-
.orElseThrow(() -> new EasyPlusOauth2AuthenticationException(
164-
EasyPlusErrorMessages.builder()
165-
.message("Header parsing error (header : " + authorizationHeader + ")")
166-
.userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_WRONG_CLIENT_ID_SECRET))
167-
.build()));
168-
169-
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
170-
171-
// Registered Client 검증
172-
@NotNull RegisteredClient registeredClient = registeredClientRepository.findByClientId(basicCredentials.getClientId());
173-
oauth2AuthenticationHashCheckService.validateClientCredentials(basicCredentials.getClientSecret(), registeredClient);
174-
175-
// UserDetails 로드 및 Username/Password 검증
176-
@NotNull UserDetails userDetails = conditionalDetailsService.loadUserByUsername(authorizationCodeRequest.getUsername(), basicCredentials.getClientId());
177-
oauth2AuthenticationHashCheckService.validateUsernamePassword(authorizationCodeRequest.getPassword(), userDetails);
178-
179-
// Authorization Code 생성 및 저장
180-
Map<String, Object> additionalParameters = RequestOAuth2Distiller.getTokenUsingSecurityAdditionalParameters(request);
181-
additionalParameters.put(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.AUTHORIZATION_CODE.getValue());
182-
@NotNull OAuth2Authorization oAuth2Authorization = commonOAuth2AuthorizationSaver.save(userDetails, AuthorizationGrantType.AUTHORIZATION_CODE, basicCredentials.getClientId(), additionalParameters, null);
183-
184-
// Authorization Code 추출
185-
String authorizationCode = oAuth2Authorization.getToken(OAuth2AuthorizationCode.class).getToken().getTokenValue();
186-
187-
// Authorization Code Response 반환
188-
return new SpringSecurityTraditionalOauthDTO.AuthorizationCodeResponse(authorizationCode);
189-
190145
} catch (UsernameNotFoundException e) {
191-
throw new EasyPlusOauth2AuthenticationException(
192-
EasyPlusErrorMessages.builder().message(e.getMessage())
193-
.userMessage(e.getMessage())
194-
.build());
146+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(e.getMessage()).build(), e);
195147
} catch (EasyPlusOauth2AuthenticationException e) {
196148
throw e;
197149
} catch (Exception e) {
198-
throw new EasyPlusOauth2AuthenticationException(
199-
EasyPlusErrorMessages.builder().message(e.getMessage())
200-
.userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_LOGIN_ERROR))
201-
.build());
150+
throw new EasyPlusOauth2AuthenticationException(EasyPlusErrorMessages.builder().message(e.getMessage()).userMessage(iSecurityUserExceptionMessageService.getUserMessage(DefaultSecurityUserExceptionMessage.AUTHENTICATION_LOGIN_ERROR)).build(), e);
202151
}
203152
}
204153

0 commit comments

Comments
 (0)