SpringBoot 3.0.1 로 업데이트 후 OAuth2 로 소셜 로그인을 진행하는데
계속 token을 받아올 수 없는 현상이 발생했다.
[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]
분명 client-authentication-method: post 를 잘 적어주었고
client-id, client-secret 까지 틀림없이 적었는데 오류가 계속 났다..
구글을 다 찾아보고 공식 문서를 뒤져봤지만 도무지 찾을 수 없었다.
하지만 카카오 api 에서 secret 기능을 끄면 소셜 로그인이 잘 됐다.
secret 코드 쪽이 문제구나 싶어서 이쪽을 중점으로 디버깅 해보았다.
3일 삽질 후 찾아낸 결과이다.
아래의 클래스가 문제였다.
public class OAuth2AuthorizationCodeGrantRequestEntityConverter
extends AbstractOAuth2AuthorizationGrantRequestEntityConverter<OAuth2AuthorizationCodeGrantRequest> {
@Override
protected MultiValueMap<String, String> createParameters(
OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) {
ClientRegistration clientRegistration = authorizationCodeGrantRequest.getClientRegistration();
OAuth2AuthorizationExchange authorizationExchange = authorizationCodeGrantRequest.getAuthorizationExchange();
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add(OAuth2ParameterNames.GRANT_TYPE, authorizationCodeGrantRequest.getGrantType().getValue());
parameters.add(OAuth2ParameterNames.CODE, authorizationExchange.getAuthorizationResponse().getCode());
String redirectUri = authorizationExchange.getAuthorizationRequest().getRedirectUri();
String codeVerifier = authorizationExchange.getAuthorizationRequest()
.getAttribute(PkceParameterNames.CODE_VERIFIER);
if (redirectUri != null) {
parameters.add(OAuth2ParameterNames.REDIRECT_URI, redirectUri);
}
if (!ClientAuthenticationMethod.CLIENT_SECRET_BASIC.equals(clientRegistration.getClientAuthenticationMethod())
&& !ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) {
parameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId());
}
if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientRegistration.getClientAuthenticationMethod())
|| ClientAuthenticationMethod.POST.equals(clientRegistration.getClientAuthenticationMethod())) {
parameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret());
}
if (codeVerifier != null) {
parameters.add(PkceParameterNames.CODE_VERIFIER, codeVerifier);
}
return parameters;
}
}
SpringBoot 2.x 버전의 security-oauth2-client 코드중
OAuth2AuthorizationCodeGrantRequestEntityConverter 클래스의 코드이다.
if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientRegistration.getClientAuthenticationMethod())
|| ClientAuthenticationMethod.POST.equals(clientRegistration.getClientAuthenticationMethod())) {
parameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret());
}
이 부분을 보면 oauth2 관련 properties나 yml을 작성할 때
client-authentication-method: post
OR
client-authentication-method: client_secret_post
를 작성해주면 if문이 true가 돼서 파라미터가 추가가 됐었다.
하지만...
public class OAuth2AuthorizationCodeGrantRequestEntityConverter
extends AbstractOAuth2AuthorizationGrantRequestEntityConverter<OAuth2AuthorizationCodeGrantRequest> {
@Override
protected MultiValueMap<String, String> createParameters(
OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) {
ClientRegistration clientRegistration = authorizationCodeGrantRequest.getClientRegistration();
OAuth2AuthorizationExchange authorizationExchange = authorizationCodeGrantRequest.getAuthorizationExchange();
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add(OAuth2ParameterNames.GRANT_TYPE, authorizationCodeGrantRequest.getGrantType().getValue());
parameters.add(OAuth2ParameterNames.CODE, authorizationExchange.getAuthorizationResponse().getCode());
String redirectUri = authorizationExchange.getAuthorizationRequest().getRedirectUri();
String codeVerifier = authorizationExchange.getAuthorizationRequest()
.getAttribute(PkceParameterNames.CODE_VERIFIER);
if (redirectUri != null) {
parameters.add(OAuth2ParameterNames.REDIRECT_URI, redirectUri);
}
if (!ClientAuthenticationMethod.CLIENT_SECRET_BASIC
.equals(clientRegistration.getClientAuthenticationMethod())) {
parameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId());
}
if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientRegistration.getClientAuthenticationMethod())) {
parameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret());
}
if (codeVerifier != null) {
parameters.add(PkceParameterNames.CODE_VERIFIER, codeVerifier);
}
return parameters;
}
}
SpringBoot 3.x의 security-oauth2-client 코드이다.
다른 점이 보이는가
if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientRegistration.getClientAuthenticationMethod())) {
parameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret());
}
POST 가 사라졌다!!! 이런...
그래서 client-authentication-method: post 를 해도 요청 파라미터에 client-secret 값이 추가가 안되는 것 이었다..........
결론
client-authentication-method: client_secret_post 으로 해주면 해결할 수 있다. (대문자도 안됨)
'SpringBoot' 카테고리의 다른 글
[SpringBoot] JPA N+1 문제를 @EntityGraph로 해결하기 (0) | 2023.09.16 |
---|