Java 在 spring 中通过 resttemplate 发出的每个请求发送客户端证书的正确方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45713593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the right way to send a client certificate with every request made by the resttemplate in spring?
提问by Nas3nmann
i want to consume a REST service with my spring application. To access that service i have a client certificate (self signed and in .jks format) for authorization. What is the proper way to authenticate against the rest service?
我想用我的 spring 应用程序使用 REST 服务。要访问该服务,我有一个用于授权的客户端证书(自签名和 .jks 格式)。针对其余服务进行身份验证的正确方法是什么?
This is my request:
这是我的要求:
public List<Info> getInfo() throws RestClientException, URISyntaxException {
HttpEntity<?> httpEntity = new HttpEntity<>(null, new HttpHeaders());
ResponseEntity<Info[]> resp = restOperations.exchange(
new URI(BASE_URL + "/Info"), HttpMethod.GET,
httpEntity, Info[].class);
return Arrays.asList(resp.getBody());
}
采纳答案by Ruslan Poshuk
Here is example how to do this using RestTemplateand Apache HttpClient
以下是如何使用RestTemplate和Apache HttpClient执行此操作的示例
You should define your own RestTemplate
with configured SSL context:
您应该RestTemplate
使用配置的 SSL 上下文定义自己的上下文:
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
char[] password = "password".toCharArray();
SSLContext sslContext = SSLContextBuilder.create()
.loadKeyMaterial(keyStore("classpath:cert.jks", password), password)
.loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
HttpClient client = HttpClients.custom().setSSLContext(sslContext).build();
return builder
.requestFactory(new HttpComponentsClientHttpRequestFactory(client))
.build();
}
private KeyStore keyStore(String file, char[] password) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
File key = ResourceUtils.getFile(file);
try (InputStream in = new FileInputStream(key)) {
keyStore.load(in, password);
}
return keyStore;
}
Now all remote calls performed by this template will be signed with cert.jks
.
Note: You would need to put cert.jks
into your classpath
现在,此模板执行的所有远程调用都将使用cert.jks
.
注意:您需要放入cert.jks
类路径
@Autowired
private RestTemplate restTemplate;
public List<Info> getInfo() throws RestClientException, URISyntaxException {
HttpEntity<?> httpEntity = new HttpEntity<>(null, new HttpHeaders());
ResponseEntity<Info[]> resp = restTemplate.exchange(
new URI(BASE_URL + "/Info"), HttpMethod.GET,
httpEntity, Info[].class);
return Arrays.asList(resp.getBody());
}
回答by Abhijeet
Or you can just import the certificate to your JDKs cacerts, and all the HTTP clients using the jdk (rest template in your case) will use the certificate to make the REST call.
或者,您可以将证书导入到您的 JDK cacerts 中,所有使用 jdk(在您的示例中为 REST 模板)的 HTTP 客户端都将使用该证书进行 REST 调用。
keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file foo.cer -alias alias
P.S: Don't forget to restart your server after successful import. Default password for keystore - changeit
PS:导入成功后不要忘记重启服务器。密钥库的默认密码 -changeit