发送请求时作为身份验证的 RestTemplate X509 证书

时间:2021-01-12 19:05:25

标签: java ssl-certificate x509certificate resttemplate apache-httpclient-4.x

本来应该很简单的事情被证明是一场噩梦。我有两个 webapps - 第一个 (webapp1) 应该使用 RestTemplate 和密钥库中的 X509 证书发布到另一个 (webapp2),第二个 (webapp2) 过滤请求并检查 X509 证书的有效性这是信任库。

我在自定义 RestTemplate bean 中的 webapp1 中使用 ApacheHttp,如下所示:

@Bean
public RestTemplate restTemplate() {
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(this.httpClient());

    RestTemplate restTemplate = new RestTemplate(factory);
    restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    restTemplate.getInterceptors().add(new RestTemplateHeaderModifierInterceptor());
    restTemplate.setRequestFactory(factory);
        
    return restTemplate;
}

public SSLConnectionSocketFactory sslConnectionSocketFactory() throws Exception {
    return new SSLConnectionSocketFactory(sslContext(), NoopHostnameVerifier.INSTANCE);
}

@Bean
public HttpClient httpClient() throws Exception {
    return HttpClientBuilder.create().setSSLSocketFactory(sslConnectionSocketFactory())
            .addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor()).build();
}

private SSLContext sslContext() throws Exception {
    return SSLContextBuilder.create()
            .loadKeyMaterial(resourceLoader.getResource(keyStorePath).getFile(), keyStorePassword.toCharArray(), keyStorePassword.toCharArray())
            .loadTrustMaterial(resourceLoader.getResource(trustStorePath).getFile(), trustStorePassword.toCharArray())
            .build();
}

在 webapp2 中,我使用 X509AuthenticationFilter 应该为我获取一个 PreAuthenticatedAuthenticationToken 然后可以通过以下方式访问:

SecurityContextHolder.getContext().getAuthentication()

唉,webapp2 说身份验证对象为空(当从邮递员使用正确的证书发布时,请求成功并且对象不为空),因此我无法从中提取 X509 证书以进行进一步验证。请求似乎没有到达 RestTemplate 应该通过 ApacheHttp 工厂附加的证书。当我在 RestTemplate.exchange(...) 之前调试代码时,我可以看到工厂有一个 HttpClient 对象,该对象包含一个 SSLSocketFactory,其中附加了来自指定密钥库的证书。

据我所知,这应该是开箱即用的,但似乎我遗漏了一块拼图。我已经用尽了许多代码重写,但都是徒劳的。我似乎无法确定 RestTemplate 的证书身份验证是如何工作的。有人能指出我正确的方向吗?

另外值得一提的是,webapp1 中的信任库部分有效(接收到 SSL 握手)。此外,密钥库和信任库均已正确加载并且其中的正确证书已被使用,我可以看到很多。

0 个答案:

没有答案
相关问题