gpt4 book ai didi

spring - 如何使用 RestTemplate 进行基本身份验证

转载 作者:行者123 更新时间:2023-12-02 06:40:25 29 4
gpt4 key购买 nike

如何使用 Apache httpclient 4.3.2 配置 Spring 4.0.3.RELEASE 中的 RestTemplate?我遵循了 SO here 中的代码,和here ,甚至来自 Apache here ,看起来很简单,但它从来没有对我有用。当我使用curl和postman时,我可以验证授权 header 是否正确发送,但授权 header 永远不会使用以下代码发送:

public RestTemplate createBasicAuthTemplate(String username, String password) {
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
HttpClient httpClient = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credentialsProvider)
.build();

ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate template = new RestTemplate(requestFactory);

return template;
}

代码的调用方式如下:

RestTemplate basicAuth = createBasicAuthTemplate("user@app.com", "password");
ResponseEntity<String> response = basicAuth.getForEntity(url, String.class);

所以问题是:如何使用 Apache httpclient 4.3.2 配置 Spring 4.0.3.RELEASE 中的 RestTemplate?上面的代码还缺少其他部分吗?上面代码中的RestTemplate使用方法正确吗?

最佳答案

精明的读者可能已经注意到授权 header 从未发送,并意识到了问题所在。你只需要知道这是一个标准协议(protocol),用于发送未经授权的请求,接收带有 WWW-Authenticate header 的 401,并使用 Authorization header 再次发出请求(我不知道,所以这是一个很棒的 learning experience ) .

其余模板不会在初始请求上发送 Authentication header (默认情况下,它是被动式的而不是主动式的),因此如果服务不使用 WWW-Authenticate header 进行响应(根据 HTTP 规范,它应该如此)并且 RestTemplate 在初始响应后不会尝试发送凭据,那么调用将在初始 401 响应时失败。

幸运的是,我们可以告诉其余模板在初始请求时发送凭据,而不是等待带有 WWW-Authenticate header 的 401。

这是执行此操作的代码。这里的技巧是重写请求工厂的 createHttpContext() 方法来控制 HTTP 上下文,并在构造 RestTemplate 时使用该工厂。此代码有效,并使用自签名证书。您当然可以根据您的口味重新构造它......

public class BasicRequestFactory extends HttpComponentsClientHttpRequestFactory {

public BasicRequestFactory(HttpClient httpClient) {
super(httpClient);
}

@Override
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
AuthCache authCache = new BasicAuthCache();
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
return localContext;
}

private static HttpClient createSecureClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).useTLS().build();
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
return HttpClientBuilder.create().setSSLSocketFactory(connectionFactory).build();
}

private static HttpClient createSecureClient(String username, String password) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).useTLS().build();
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
return HttpClientBuilder.create().setSSLSocketFactory(connectionFactory).setDefaultCredentialsProvider(credentialsProvider).build();
}

public static RestTemplate createTemplate(String username, String password) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
RestTemplate template = new RestTemplate(new BasicRequestFactory(createSecureClient(username, password)));
template.setErrorHandler(new NopResponseErrorHandler());
return template;
}

public static RestTemplate createTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
RestTemplate template = new RestTemplate(new BasicRequestFactory(createSecureClient()));
template.setErrorHandler(new NopResponseErrorHandler());
return template;
}

private static class NopResponseErrorHandler implements ResponseErrorHandler {

@Override
public boolean hasError(ClientHttpResponse chr) throws IOException {
return false;
}

@Override
public void handleError(ClientHttpResponse chr) throws IOException {
}
}

}

关于spring - 如何使用 RestTemplate 进行基本身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23207928/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com