Jersey客户端基础认证

3

我正在尝试通过HTTPS发送包含HTTP头中基本身份验证的REST请求,问题似乎是身份验证没有被插入到头部中。

    HttpAuthenticationFeature feature = HttpAuthenticationFeature
            .basicBuilder().build();

    Client client = ClientBuilder.newBuilder().sslContext(getSSLContext())
            .hostnameVerifier(getHostNameVerifier()).build();
    client.register(feature);
    client.register(new LoggingFilter());
    try
    {
        String entity = client
                .target(url)
                .request(MediaType.APPLICATION_XML)
                .property(
                        HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_USERNAME,
                        "username")
                .property(
                        HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_PASSWORD,
                        "password").get(String.class);

        System.out.println(entity);
    } catch (WebApplicationException e)
    {
        ByteArrayInputStream in = (ByteArrayInputStream) e.getResponse()
                .getEntity();
        int n = in.available();
        byte[] bytes = new byte[n];
        in.read(bytes, 0, n);
        String entity = new String(bytes, StandardCharsets.UTF_8);
        System.out.println(entity);
    }

日志记录内容:
Jun 16, 2015 2:06:53 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Sending client request on thread JavaFX Application Thread
1 > GET https://url
1 > Accept: application/xml

Jun 16, 2015 2:06:53 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * Client response received on thread JavaFX Application Thread
2 < 403
2 < Connection: Keep-Alive
2 < Content-Length: 240
2 < Content-Type: text/html; charset=iso-8859-1
2 < Date: Tue, 16 Jun 2015 12:06:53 GMT
2 < Keep-Alive: timeout=15, max=100

结果代码只是403 Forbidden。

如果我删除client.register(feature);这一行,那么2 < WWW-authenticate: basic realm="/"这一行会被添加到日志的末尾,并且结果代码将变为401 Authorization Requried而不是403。

在FireFox中使用HTTP请求器时,REST请求正常工作。

我想我可能在某个地方遗漏了什么?


你确定凭证(“用户名”和“密码”)是有效的吗? - Jan
你有记录原始请求并将其复制到您的帖子中的可能性吗?原始请求应包含类似于“Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=”的头。 - Roman Vottner
日志是请求 + 响应头,正如您所看到的,请求头中不包含Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=行。 - vonyx
@vonyx,你已经尝试过这个方法了吗? - Roman Vottner
@RomanVottner 是的,同样的结果令人遗憾。 - vonyx
1个回答

4
如果您需要使用Pre-Jersey 2.X,那么这可能会很困难,这一点显而易见。如果您需要进行HTTPS(SSL)基本身份验证,则从Jersey 2.X开始变得非常容易。
这些说明使用的是Jersey 2.25.1:
  1. 如果您使用的是自签名证书,则必须首先从浏览器中的HTTPS页面下载.cer/.crt/.cet文件,并使用有效登录进行身份验证。 指南, SO答案
  2. 然后,在Jersey 2.X中使用不同的Feature (javax.ws.rs.core)实现来输入所有这些信息。

构建具有SSLContext的WebTarget和Client的示例代码:

HttpAuthenticationFeature auth = HttpAuthenticationFeature.basic("admin", password);
SslConfigurator config = SslConfigurator.newInstance()
        .keyStoreFile("C:\Program Files\Java\jdk\jre\lib\security\cacerts")
        .keyPassword("changeit");
SSLContext sslContext = config.createSSLContext();
Client client = ClientBuilder.newBuilder()
        .sslContext(sslContext)
        .register(SseFeature.class)
        .register(auth)
        .build();
WebTarget target = client.target(sourcePath);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接