client-credentials 방식 accessToken null 이슈
214
작성자 없음
작성한 질문수 0
Cannot invoke "org.springframework.security.oauth2.client.OAuth2AuthorizedClient.getAccessToken()" because "oAuth2AuthorizedClient" is null] with root cause
keycloak 버전은 : 21.1.2
@GetMapping("/oauth2Login")
public String oauth2Login(Model model, HttpServletRequest request, HttpServletResponse response) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
OAuth2AuthorizeRequest oAuth2AuthorizeRequest = OAuth2AuthorizeRequest
.withClientRegistrationId("keycloak")
.principal(authentication)
.attribute(HttpServletRequest.class.getName(), request)
.attribute(HttpServletResponse.class.getName(), response)
.build();
OAuth2AuthorizationSuccessHandler successHandler = (authorizedClient, principal, attributes) -> {
oAuth2AuthorizedClientRepository
.saveAuthorizedClient(authorizedClient, principal,
(HttpServletRequest) attributes.get(HttpServletRequest.class.getName()),
(HttpServletResponse) attributes.get(HttpServletResponse.class.getName()));
System.out.println("authorizedClient : " + authorizedClient);
System.out.println("principal : " + principal);
System.out.println("attributes : " + attributes);
};
auth2AuthorizedClientManager.setAuthorizationSuccessHandler(successHandler);
OAuth2AuthorizedClient oAuth2AuthorizedClient = auth2AuthorizedClientManager.authorize(oAuth2AuthorizeRequest);
model.addAttribute("oAuth2AuthorizedClient", oAuth2AuthorizedClient.getAccessToken().getTokenValue());
return "home";
}
keycloak:
clientId: oauath2-client-app
clientSecret: HPWAsKr9dEy9DPU1babedRmpstowiXOs
clientName: oauath2-client-app
authorizationGrantType: client-credentials
clientAuthenticationMethod: client_secret_basic
provider: keycloak
<form sec:authorize="isAnonymous()" action="#">
<p><input type="button" onclick="authorizationCode()" value="AuthorizationCode Grant"/></p>
<p><div sec:authorize="isAnonymous()"><a th:href="@{/oauth2Login(username='user',password='1234')}">Password flow</a></div></p>
<div sec:authorize="isAnonymous()"><a th:href="@{/oauth2Login}">Client Credentials Flow Login</a></div>
</form>
@Configuration
public class AppConfig {
@Bean
public DefaultOAuth2AuthorizedClientManager auth2AuthorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository oAuth2AuthorizedClientRepository) {
OAuth2AuthorizedClientProvider oAuth2AuthorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.password()
.clientCredentials()
.refreshToken()
.build();
DefaultOAuth2AuthorizedClientManager defaultOAuth2AuthorizedClientManager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, oAuth2AuthorizedClientRepository);
defaultOAuth2AuthorizedClientManager.setAuthorizedClientProvider(oAuth2AuthorizedClientProvider);
defaultOAuth2AuthorizedClientManager.setContextAttributesMapper(contextAttributeManager());
return defaultOAuth2AuthorizedClientManager;
}
private Function<OAuth2AuthorizeRequest, Map<String, Object>> contextAttributeManager() {
return oAuth2AuthorizeRequest -> {
Map<String, Object> contextAttributes = new HashMap<>();
HttpServletRequest httpServletRequest = oAuth2AuthorizeRequest.getAttribute(HttpServletRequest.class.getName());
String userName = httpServletRequest.getParameter(OAuth2ParameterNames.USERNAME);
String userPassword = httpServletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
if(StringUtils.hasText(userName) && StringUtils.hasText(userPassword)) {
contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, userName);
contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, userPassword);
}
return contextAttributes;
};
}
}
이렇게 됩니다. 현재 상황으로 문제가 되어 있는 부분이 없는 것 같습니다.
어디부터 다시 확인해야 될지 조언 부탁드립니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
JUNI님의 코드와 설정을 검토해 본 결과, client-credentials 방식과 관련하여 문제를 겪고 계신 것으로 보입니다. client-credentials 그랜트 타입은 클라이언트가 서버에 직접 인증하는 상황에 사용되며, 일반적으로 사용자와 관련된 권한이 아닌 클라이언트 자체의 권한에 대해 적용됩니다. 하지만 주신 코드는 사용자 인증을 기반으로 하는 코드로 보입니다.
client-credentials 방식으로 액세스 토큰을 얻으려면, 먼저 OAuth2AuthorizedClientManager나 OAuth2AuthorizedClientProvider에서 client-credentials 방식을 지원하도록 설정되어 있어야 합니다. 또한, 사용자 인증 과정이 아니므로 Authentication 객체 없이 클라이언트 인증 정보만으로 액세스 토큰을 요청해야 합니다.
현재 제공하신 내용에는 OAuth2AuthorizedClientManager와 OAuth2AuthorizedClientProvider의 설정 관련 내용이 누락되어 있습니다. 따라서 다음을 확인해 주세요:
OAuth2AuthorizedClientManager와 어떻게 설정되어 있는지, 특히client-credentials를 처리할 수 있는OAuth2AuthorizedClientProvider가 포함되어 있는지 확인하세요.
client-credentials사용 시Authentication객체 대신 클라이언트의 인증 정보만을 사용하여 토큰을 요청하는 코드로 변경이 필요할 수 있습니다.
프로그램의 나머지 부분에 오류가 없다면 이 점을 검토하셔서 문제를 해결해 보시기 바랍니다.
authorization-server 라이브러리 질문이 있습니다.
0
81
1
loadUser 중 Missing attribute 'preferred_username' in attributes 에러 발생
0
85
2
JWT 조회 에 대한 질문
0
79
1
password grant 방식 에러 응답
0
100
3
FormLoginConfigure에서 생성하는 필터
0
79
2
현업에서 springboot를 3.5.5 를 사용해서 공부중인데...
0
291
2
Jdbc 관련 강의 및 깃헙 문의
0
79
1
OAuth2AuthorizedClient 이해 및 활용 강의 내용 질문
0
209
1
UserInfo 엔드포인트 요청 실습
0
76
1
RFC 문서에서의 AccessToken 발급 방식 궁금한점
0
153
1
강의자료.zip 를 다운로드 받았는데 압축이 풀리지 않습니다. 확인 부탁드려요
0
141
2
OIDC SSO 관련 질문 입니다.
0
131
1
AuthenticationEntryPoint 강의 누락 문의
0
125
1
cors설정방법
0
116
1
jwt decoder 토큰 검증 시 질문
0
224
1
클라이언트에서 userinfo 엔드포인트 호출 시 질문
0
188
2
JOSE 구성요소의 api에 관한 질문
0
142
2
스프링 부트 3버전으로 따라가시는 분들 참고하세요
1
535
1
CustomOAuth2AuthenticationFilter 구현 중 질문
0
146
2
AuthenticationManager 생성시점
0
118
1
FormLogin과 Oauth2Client 둘 중 사용하는 시점
0
128
1
postman userinfo 엔드포인트 질문
0
137
2
강의 수강신청하고 듣기 전입니다 질문있습니다.
0
117
1
인증 코드를 통해 발급 받은 토큰의 관리
0
202
1





