작성자 없음
작성자 정보가 삭제된 글입니다.
작성
·
92
·
수정됨
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
객체 대신 클라이언트의 인증 정보만을 사용하여 토큰을 요청하는 코드로 변경이 필요할 수 있습니다.프로그램의 나머지 부분에 오류가 없다면 이 점을 검토하셔서 문제를 해결해 보시기 바랍니다.