我正在尝试使用 OAuth2RestTemplate 访问自签名证书以通过 HTTPS 检索令牌,但我仍然收到此错误:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: 没有与本地主机匹配的名称 发现
这是我抛出错误的单元测试:
public class OAuth2ClientTest {
private static final Logger logger = LoggerFactory
.getLogger(SecurityConfig.class);
@Value("${oauth.resource:https://localhost:8443}")
private String baseUrl;
@Value("${oauth.token:https://localhost:8443/oauth/token}")
private String tokenUrl;
@Value("${oauth.resource.id:microservice-test}")
private String resourceId;
@Value("${oauth.resource.client.id:client1}")
private String resourceClientId;
@Value("${oauth.resource.client.secret:changit}")
private String resourceClientSecret;
@Test
public void execute_post_to_tokenUrl()
throws ClientProtocolException, IOException {
OAuth2RestTemplate template = template();
ResponseEntity<String> response = template.exchange(
tokenUrl,
HttpMethod.POST,
null,
String.class);
assertThat(response.getStatusCode().value(), equalTo(200));
}
private OAuth2RestTemplate template(){
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setAccessTokenUri(tokenUrl);
resource.setId(resourceId);
resource.setClientId(resourceClientId);
resource.setClientSecret(resourceClientSecret);
resource.setGrantType("password");
resource.setScope(Arrays.asList("openid"));
resource.setUsername("user1@example.com");
resource.setPassword("user1");
OAuth2RestTemplate template = new OAuth2RestTemplate(resource);
ClientHttpRequestFactory factory = template.getRequestFactory();
template.setRequestFactory(requestFactory());
return template;
}
private HttpComponentsClientHttpRequestFactory requestFactory(){
CloseableHttpClient httpClient
= HttpClients.custom()
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return requestFactory;
}
}
当我使用非HTTPS连接时,OAuth2代码工作正常。只是不使用HTTPS
如果您希望TLS正常工作,则必须创建别名为"localhost"的证书。
另一种可能性是静态或在测试配置中设置它:
final HostnameVerifier defaultHostnameVerifier = javax.net.ssl.HttpsURLConnection.getDefaultHostnameVerifier ();
final HostnameVerifier localhostAcceptedHostnameVerifier = new javax.net.ssl.HostnameVerifier () {
public boolean verify ( String hostname, javax.net.ssl.SSLSession sslSession ) {
if ( hostname.equals ( "localhost" ) ) {
return true;
}
return defaultHostnameVerifier.verify ( hostname, sslSession );
}
};
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier ( localhostAcceptedHostnameVerifier );
。