Spring Security 5 Application Runner에서 OAuth2 Secured API를 호출하면 잘못된 인수가 발생함예외.
다음 코드가 주어지면 애플리케이션 실행기에서 클라이언트 자격 증명 보안 API를 호출할 수 있습니까?
@Bean
public ApplicationRunner test(
WebClient.Builder builder,
ClientRegistrationRepository clientRegistrationRepo,
OAuth2AuthorizedClientRepository authorizedClient) {
return args -> {
try {
var oauth2 =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrationRepo,
authorizedClient);
oauth2.setDefaultClientRegistrationId("test");
var response = builder
.apply(oauth2.oauth2Configuration())
.build()
.get()
.uri("test")
.retrieve()
.bodyToMono(String.class)
.block();
log.info("Response - {}", response);
} catch (Exception e) {
log.error("Failed to call test.", e);
}
};
}
다음으로 인해 코드가 실패합니다.
java.lang.IllegalArgumentException: request cannot be null
전체 스택,
java.lang.IllegalArgumentException: request cannot be null
at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository.loadAuthorizedClient(HttpSessionOAuth2AuthorizedClientRepository.java:47) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.populateDefaultOAuth2AuthorizedClient(ServletOAuth2AuthorizedClientExchangeFilterFunction.java:364) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.lambda$null$2(ServletOAuth2AuthorizedClientExchangeFilterFunction.java:209) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.web.reactive.function.client.DefaultWebClient$DefaultRequestBodyUriSpec.attributes(DefaultWebClient.java:234) ~[spring-webflux-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.reactive.function.client.DefaultWebClient$DefaultRequestBodyUriSpec.attributes(DefaultWebClient.java:153) ~[spring-webflux-5.1.5.RELEASE.jar:5.1.5.RELEASE]
실패하는 방법은 다음과 같습니다.
public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(
String clientRegistrationId, Authentication principal, HttpServletRequest request){
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
Assert.notNull(request, "request cannot be null");
return (OAuth2AuthorizedClient)this
.getAuthorizedClients(request)
.get(clientRegistrationId);
}
그것은 말이 된다 없는 것처럼.HttpServletRequest
응용프로그램을 시작할 때 호출됩니다.
나만의 no-op을 만드는 것 외에 다른 해결 방법이 있습니까?OAuth2AuthorizedClientRepository
?
//편집,
이것은 완전히 반응하는 스택이 아닙니다.사용 중인 Web Client가 포함된 Spring 웹 스택입니다.
나는 그것을 잘 알고 있습니다.ServerOAuth2AuthorizedClientExchangeFilterFunction
이는 완전 반응성 스택에 적용되며 다음과 같은 요구사항이 있습니다.ReactiveClientRegistrationRepository
그리고.ReactiveOauth2AuthorizedClient
이는 반응형이 아닌 서블릿 스택 위에 구축된 애플리케이션이기 때문에 사용할 수 없습니다.
저도 이 문제를 우연히 발견했기 때문에 다른 사람들이 쉽게 찾을 수 있도록 Darren Forsyeth의 업데이트된 답변에 대해 조금 더 자세히 설명하겠습니다.
OP가 제출한 문제는 다음과 같은 결과를 초래했습니다.OAuth2AuthorizedClientManager
할 수 있는
HttpServletRequest 컨텍스트 외부에서 운영(예: 예약/백그라운드 스레드 및/또는 서비스 계층)
(공식 문서에서)
앞서 언급한 구현,AuthorizedClientServiceOAuth2AuthorizedClientManager
에 전달됩니다.ServletOAuth2AuthorizedClientExchangeFilterFunction
기본값을 대체합니다.
이 예에서는 다음과 같이 보입니다.
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientService clientService)
{
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(
clientRegistrationRepository, clientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager)
{
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(
authorizedClientManager);
oauth2.setDefaultClientRegistrationId("keycloak");
return WebClient.builder().apply(oauth2.oauth2Configuration()).build();
}
스프링 보안팀에 물어봤는데,
https://github.com/spring-projects/spring-security/issues/6683
안타깝게도 서블릿 스택에서 백그라운드 스레드에서 순수 Spring Security 5 API를 사용하여 OAuth2 리소스를 호출하는 경우에는OAuth2AuthorizedClientRepository
이용할 수 있는.
현실적으로 두 가지 선택지가 있습니다
- 완전한 no-op 버전을 구현합니다.
var oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepo,
new OAuth2AuthorizedClientRepository() {
@Override
public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String s,
Authentication authentication, HttpServletRequest httpServletRequest) {
return null;
}
@Override
public void saveAuthorizedClient(OAuth2AuthorizedClient oAuth2AuthorizedClient,
Authentication authentication, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
}
@Override
public void removeAuthorizedClient(String s, Authentication authentication,
HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
}
});
- 의 서블릿 버전 구현
UnAuthenticatedServerOAuth2AuthorizedClientRepository
인증되지 않은 서버OAuth2Auth2Auth2AuthorizedClientRepository GitHub 소스는 순수한 no-op보다 몇 가지 기본 기능을 가지고 있습니다.
GitHub 문제에 대한 피드백을 제공하면 Spring Security 팀이 PR을 수락하고 서블릿 버전을 유지하는 것을 평가하는 데 도움이 될 수 있습니다. UnAuthenticatedServerOAuth2AuthorizedClientRepository
저는 Spring Security Team Spring Security Issue 6683과 그 뒷면에 있는 Servlet 버전의 Spring Security Issue에 연락했습니다.ServerOAuth2AuthorizedClientExchangeFilterFunction
Spring Security 5.2에 추가되어 비 http 스레드에서 사용할 수 있습니다.
언급URL : https://stackoverflow.com/questions/55308918/spring-security-5-calling-oauth2-secured-api-in-application-runner-results-in-il
'programing' 카테고리의 다른 글
이클립스, 서브클립스 및 전복용 SVN 플러그인의 장단점은 무엇입니까? (0) | 2023.07.05 |
---|---|
이전 버전의 R 패키지 설치 (0) | 2023.07.05 |
VBA: 테이블(목록 개체)의 행 수 계산 (0) | 2023.07.05 |
Oracle에서 VARCHAR의 XMLTYPE을 변환하는 방법은 무엇입니까? (0) | 2023.06.30 |
Firebase 프로젝트 ID의 이름을 변경하려면 어떻게 해야 합니까? (0) | 2023.06.30 |