我无法为http摘要认证的休息服务实现客户端。使用CURL我可以正确调用服务:
curl -v --digest -u "username:password" -H "Content-Type: application/json" --data @entity.json http://<server>:<port>/path
其中entity.json包含要发送到服务器的实体对象的JSON结构
使用wireshark我可以看到发送HTTP POST的跟踪,并且收到授权的服务器响应401。发送使用正确组合md5密码nounce等的新帖子,并使用json响应实体对象接收200 OK。一切都很好。
我试图用jersey 2.x实现这个:
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.client.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class RestApi
{
private static final Logger log = LoggerFactory.getLogger(RestApi.class)
private Client client;
private String server;
private String username;
private String password;
public RestApi(String server, String username, String password) {
this.server = server;
this.username = username;
this.password = password;
}
public Client getClient() {
if(this.client == null) {
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest(username, password);
this.client = ClientBuilder.newClient();
this.client.register(feature)
}
return this.client;
}
public <T> T post(
final String path,
final Object bodyValue,
final Class<T> c) throws RestPostException {
log.debug("POST path='{}', server='{}', bodyValue='{}'", path, server, bodyValue );
WebTarget webTarget = getClient().target(server).path(path);
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON_TYPE);
Response response = invocationBuilder.post(Entity.entity(bodyValue, MediaType.APPLICATION_JSON_TYPE));
if (response.getStatus() != 200) {
String errorString = response.readEntity(String.class);
throw new RestPostException(
"POST failed to '" + server + "/" + path + "' body value: '" + bodyValue + "' : HTTP error code : " + response.getStatus() +
". Error string:" + errorString);
}
T retval = response.readEntity(c);
return retval;
}
}
从另一个类调用post方法:
String returnedValue = getRestApi().post(
path,
v,
String.class);
其中v是我在请求中发送的json对象。
使用wireshark跟踪此信息我发现POST已发送(根据跟踪,POST与我发送的curl完全相同),未经授权的401响应。发送了一个新帖子,我没有得到200 OK。相反,我得到一个新的401 Unauthorized。
有没有人有这方面的经验?您是否看到我使用Java代码的方式缺少设置,配置等?
答案 0 :(得分:0)
我无法使用&#34; HttpAuthenticationFeature.digest&#34;。
但它适用于标准的apache http客户端方式。 下面是如何使用dropwizard的JerseyClientBuilder注册CredentialsProvider的示例:
JerseyClientConfiguration configuration = config.httpClient;
HttpHost target = HttpHost.create(config.apiUrl);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(target), new UsernamePasswordCredentials(config.user, config.password));
final Client httpClient = new JerseyClientBuilder(environment)
.using(configuration)
.using(credsProvider)
.build("my-client");