我使用的是包含Spring RestTemplate.java的spring-web-4.3.6.RELEASE.jar。 我写了4个junit测试用例来调用" https"基本身份验证restfull Web服务。我已经处理了" https"通过将证书注册到java密钥库cacerts文件来解决问题。现在我得到了#34; http 401 Unauthorized"当我通过java调用restfull Web服务但不通过soapUI或postman调用时出错:
在Junit测试用例2(" testLocalCreateABCVersion2()")中,我使用了自定义ContextAwareHttpComponentsClientHttpRequestFactory.java类。我在底部提供的。
在Junit测试用例3(" testLocalCreateABCVersion3()")中,我使用了我在下面提供的自定义BasicAuthRestTemplate.java。
在Junit测试用例4(testLocalCreateABCVersion4())中,我使用了org.apache.commons.httpclient.HttpClient并将client.getParams()。setAuthenticationPreemptive(true)设置为true。这个HttpClients来自commons-httpClient-3.1.jar,并解释为什么" setAuthenticationPreemptive"存在。在org.apache.httpcomponents.httpClient_4.5.3.jar中,它不包含setAuthenticationPreemptive方法。
任何帮助或提示都会非常感激!!
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.junit.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.journaldev.spring.controller.EmpRestURIConstants;
import com.abc.model.Employee;
import com.test.TestRequestPost;
import com.test.costcontrolservice.AbcResponse;
import static org.junit.Assert.*;
import org.apache.commons.codeabc.binary.Base64;
import org.apache.http.HttpHost;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.auth.AuthScope;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.osgi.services.HttpClientBuilderFactory;
import org.apache.http.protocol.BasicHttpContext;
import javax.net.ssl.*;
import java.io.*;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import org.springframework.http.HttpHeaders;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.impl.client.HttpClientBuilder;
public class TestExample1
{
public static final String SERVER_URI_ABC_POST ="https://abc/rest/testservice/abc";
@Test
public void testLocalCreateABCVersion1()
{
try
{
String plainCreds = "idAbc:Password-Test";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic"+base64Creds);
HttpEntity<String> request = new HttpEntity<String>(headers);
RestTemplate restTemplate = new RestTemplate();
TestRequestPost TestRequestPost = new TestRequestPost();
//with basic authentication
ResponseEntity<AbcResponse> response = restTemplate.exchange(SERVER_URI_ABC_POST ,HttpMethod.POST,request, AbcResponse.class,TestRequestPost);
assertNotNull(response);
}
catch(Exception e)
{
System.out.println("e:"+e.getMessage());
}
}
@Test
public void testLocalCreateABCVersion2()
{
try
{
DefaultHttpClient client = new DefaultHttpClient();
String userId ="idAbc";
String password = "Password-Test";
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userId, password));
client.setCredentialsProvider(credentialsProvider);
ContextAwareHttpComponentsClientHttpRequestFactory customFactory = new ContextAwareHttpComponentsClientHttpRequestFactory(client);
String host = "abc/rest/testservice/abc";
int port = 443;
HttpHost targetHost = null;
targetHost = new HttpHost(host, port, "http");
// Create AuthCache instance
BasicAuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
customFactory.setHttpContext(localContext);
RestTemplate restTemplate = new RestTemplate(customFactory);
String plainCreds = "idAbc:Password-Test";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
byte[] token = java.util.Base64.getEncoder().encode(plainCreds.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic"+new String(token));
HttpEntity<String> request = new HttpEntity<String>(headers);
TestRequestPost TestRequestPost = new TestRequestPost();
//without basic authentication
//AbcResponse response = restTemplate.postForObject(SERVER_URI_ABC_POST , TestRequestPost, AbcResponse.class);
//with basic authentication
ResponseEntity<AbcResponse> response = restTemplate.exchange(SERVER_URI_ABC_POST ,HttpMethod.POST,request, AbcResponse.class,TestRequestPost);
assertNotNull(response);
}
catch(Exception e)
{
System.out.println("e:"+e.getMessage());
}
}
@Test
public void testLocalCreateABCVersion3()
{
try
{
String plainCreds = "idAbc:Password-Test";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic"+base64Creds);
HttpEntity<String> request = new HttpEntity<String>(headers);
RestTemplate restTemplate = new BasicAuthRestTemplate("idAbc","Password-Test");
TestRequestPost TestRequestPost = new TestRequestPost();
//without basic authentication
// AbcResponse response = restTemplate.postForObject(SERVER_URI_ABC_POST , TestRequestPost, AbcResponse.class);
//with basic authentication
ResponseEntity<AbcResponse> response = restTemplate.exchange(SERVER_URI_ABC_POST ,HttpMethod.POST,request, AbcResponse.class,TestRequestPost);
assertNotNull(response);
}
catch(Exception e)
{
System.out.println("e:"+e.getMessage());
}
}
@Test
public void testLocalCreateABCVersion4()
{
try
{
String plainCreds = "idAbc:Password-Test";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic"+base64Creds);
org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
client.getParams().setAuthenticationPreemptive(true);
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("idAbc","Password-Test");
client.getState().setCredentials(new AuthScope("abc",433,AuthScope.ANY_REALM),credentials);
CommonsClientHttpRequestFactory commons = new CommonsClientHttpRequestFactory(client);
RestTemplate restTemplate = new RestTemplate(commons);
HttpEntity<String> request = new HttpEntity<String>(headers);
TestRequestPost TestRequestPost = new TestRequestPost();
ResponseEntity<CostControlResponse> response = restTemplate.exchange(SERVER_URI_ABC_POST ,HttpMethod.POST,request, AbcResponse.class.class,TestRequestPost);
assertNotNull(response);
}
catch(Exception e)
{
System.out.println("e:"+e.getMessage());
}
}
}
ContextAwareHttpComponentsClientHttpRequestFactory.java:
import java.net.URI;
import org.apache.http.client.HttpClient;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
//import org.apache.commons.httpclient.HttpClient;
public class ContextAwareHttpComponentsClientHttpRequestFactory extends
HttpComponentsClientHttpRequestFactory {
private HttpContext httpContext;
public ContextAwareHttpComponentsClientHttpRequestFactory(HttpClient httpClient){
super(httpClient);
}
protected org.apache.http.protocol.HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
//Ignoring the URI and method.
return httpContext;
}
public void setHttpContext(HttpContext httpContext) {
this.httpContext = httpContext;
}
}
BasicAuthRestTemplate.java:
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
//import java.util.Base64; original
import java.util.Collections;
import java.util.List;
import org.apache.commons.codec.binary.Base64; //new
public class BasicAuthRestTemplate extends RestTemplate {
public BasicAuthRestTemplate(String username, String password) {
addAuthentication(username, password);
}
private void addAuthentication(String username, String password) {
if (username == null) {
return;
}
List<ClientHttpRequestInterceptor> interceptors = Collections
.<ClientHttpRequestInterceptor> singletonList(
new BasicAuthorizationInterceptor(username, password));
setRequestFactory(new InterceptingClientHttpRequestFactory(getRequestFactory(),
interceptors));
}
private static class BasicAuthorizationInterceptor implements
ClientHttpRequestInterceptor {
private final String username;
private final String password;
public BasicAuthorizationInterceptor(String username, String password) {
this.username = username;
this.password = (password == null ? "" : password);
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException
{
/* original code
byte[] token = Base64.getEncoder().encode(
(this.username + ":" + this.password).getBytes());
request.getHeaders().add("Authorization", "Basic " + new String(token));
return execution.execute(request, body);
*/
String plainCreds = "idAbc:Password-Test";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
request.getHeaders().add("Authorization", "Basic " + new String(base64Creds));
return execution.execute(request, body);
}
}
}
答案 0 :(得分:0)
尝试使用以下链接,它可以帮助我完成RestClient
http://howtodoinjava.com/spring/spring-restful/spring-restful-client-resttemplate-example/
我是这样做的。用您的数据替换TODO
1)从Sprint RestTemplate创建新实例。你可以把它配置为Spring bean
RestTemplate restTemplate = new RestTemplate();
2)设置安全标头
protected MultiValueMap<String, String> addSecurityHeader() {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
headers.add("Content-Type", MediaType.APPLICATION_JSON.toString());
headers.add("Authorization", TODO_BasicAuthCode);
return headers;
}
3)HttpEntity entity = new HttpEntity&lt;&gt;(TODO,addSecurityHeader());
ResponseEntity<String> response = restTemplate.exchange(getTicketUrl, HttpMethod.PUT, entity, String.class);