Http摘要身份验证失败,使用jersey 2.x,与curl一起使用

时间:2016-08-24 07:33:57

标签: rest http post jersey digest-authentication

我无法为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代码的方式缺少设置,配置等?

1 个答案:

答案 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");