OAuth2,访问/OAuth2/代理后面的令牌资源



我需要使用一个由OAuth2通过WebClient保护的API。我已经配置了OAuth2AuthorizedClientManager来管理访问令牌,并在需要时刷新它。

然而,我遇到了一些问题,java.net.UnknownHostException。在我的应用程序和OAuth2令牌资源之间有一个代理,我不知道如何配置它

我尝试过的:

  • 在没有代理的其他环境中测试它,它就可以工作了。我的OAuth2AuthorizedClientManager配置是正确的
  • System.setProperty(),不是一个解决方案,我有几个代理要管理

也许我误解了OAuth2的一些概念

这里有一些代码:

应用程序属性

spring.security.oauth2.client.registration.client.client-id=clientId
spring.security.oauth2.client.registration.client.authorization-grant-type=client_credentials
spring.security.oauth2.client.registration.client.client-secret=clientSecret
spring.security.oauth2.client.provider.client.token-uri=URI/oauth2/token

WebClientConfig

@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 oauth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2Client.setDefaultClientRegistrationId("client");
return WebClient.builder()
.baseUrl("URI")
.clientConnector(getReactorClientHttpConnector(url))
.apply(oauth2Client.oauth2Configuration())
.build();
}

我的测试

@Autowired
WebClient webClient;
public void test() {
RequestHeadersSpec<?> request = webClient.get()
.uri("/heartbeats");
}

错误

org.springframework.security.oauth2.core.OAuth2AuthorizationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: I/O error on POST request for "URI/oauth2/token": URI; nested exception is java.net.UnknownHostException: URI

我的问题是,如何为OAuth2AuthorizedClientManager配置代理

请随时要求澄清。

如有任何帮助,我们将不胜感激。感谢

我们过去也遇到过类似的问题,并通过以下配置解决了它。

@Configuration
public class AuthConfiguration {
@Bean
public JwtDecoderFactory<ClientRegistration> jwtDecoderFactory() {
return new CustomOidcIdTokenDecoderFactory(jwksRestTemplate());
}
@Bean
public DefaultAuthorizationCodeTokenResponseClient oAuth2AccessTokenResponseClient() {
var defaultAuthorizationCodeTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
defaultAuthorizationCodeTokenResponseClient.setRestOperations(tokenRestTemplate());
return defaultAuthorizationCodeTokenResponseClient;
}
@Bean
public RestTemplate jwksRestTemplate() {
return new RestTemplate(requestFactory());
}
@Bean
public RestTemplate tokenRestTemplate() {
// Copied from constructor of  DefaultAuthorizationCodeTokenResponseClient
var restTemplate = new RestTemplate(Arrays.asList(
new FormHttpMessageConverter(), new OAuth2AccessTokenResponseHttpMessageConverter()));
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
restTemplate.setRequestFactory(requestFactory());
return restTemplate;
}
private ClientHttpRequestFactory requestFactory() {
var requestFactory = new SimpleClientHttpRequestFactory();
var proxy = new Proxy(Type.HTTP, new InetSocketAddress("my.host.com", 8080));
requestFactory.setProxy(proxy);
return requestFactory;
}
}

也许这会有所帮助。此外,还需要添加以下类,因为它在Spring中是包私有的;(

package org.springframework.security.oauth2.client.oidc.authentication;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.oauth2.client.oidc.authentication.DefaultOidcIdTokenValidatorFactory;
import org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.converter.ClaimTypeConverter;
import org.springframework.security.oauth2.jose.jws.JwsAlgorithm;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoderFactory;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
import java.util.function.Function;
import static org.springframework.security.oauth2.jwt.NimbusJwtDecoder.withJwkSetUri;
/**
* extension for {@link OidcIdTokenDecoderFactory} to mock the JWKS request
*/
public class CustomOidcIdTokenDecoderFactory implements JwtDecoderFactory<ClientRegistration> {
private static final String MISSING_SIGNATURE_VERIFIER_ERROR_CODE = "missing_signature_verifier";
private static final Converter<Map<String, Object>, Map<String, Object>> DEFAULT_CLAIM_TYPE_CONVERTER =
new ClaimTypeConverter(OidcIdTokenDecoderFactory.createDefaultClaimTypeConverters());
private Function<ClientRegistration, JwsAlgorithm> jwsAlgorithmResolver = clientRegistration -> SignatureAlgorithm.RS256;
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> jwtValidatorFactory = new DefaultOidcIdTokenValidatorFactory();
private Function<ClientRegistration, Converter<Map<String, Object>, Map<String, Object>>> claimTypeConverterFactory =
clientRegistration -> DEFAULT_CLAIM_TYPE_CONVERTER;
private final RestTemplate restTemplate;
public CustomOidcIdTokenDecoderFactory(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public JwtDecoder createDecoder(ClientRegistration clientRegistration) {
NimbusJwtDecoder jwtDecoder = buildDecoder(clientRegistration);
jwtDecoder.setJwtValidator(this.jwtValidatorFactory.apply(clientRegistration));
Converter<Map<String, Object>, Map<String, Object>> claimTypeConverter =
this.claimTypeConverterFactory.apply(clientRegistration);
if (claimTypeConverter != null) {
jwtDecoder.setClaimSetConverter(claimTypeConverter);
}
return jwtDecoder;
}
private NimbusJwtDecoder buildDecoder(ClientRegistration clientRegistration) {
JwsAlgorithm jwsAlgorithm = this.jwsAlgorithmResolver.apply(clientRegistration);
String jwkSetUri = clientRegistration.getProviderDetails().getJwkSetUri();
if (!StringUtils.hasText(jwkSetUri)) {
OAuth2Error oauth2Error = new OAuth2Error(
MISSING_SIGNATURE_VERIFIER_ERROR_CODE,
"Failed to find a Signature Verifier for Client Registration: '" +
clientRegistration.getRegistrationId() +
"'. Check to ensure you have configured the JwkSet URI.",
null
);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
return withJwkSetUri(jwkSetUri).jwsAlgorithm((SignatureAlgorithm) jwsAlgorithm).restOperations(restTemplate).build();
}
}

最新更新