Apache HttpClient协商处理第二个401响应

时间:2017-10-19 21:23:04

标签: java authentication apache-httpclient-4.x spnego

我正在尝试访问使用WWW-Authenticate: Negotiate进行身份验证的HTTP服务。

我正在使用来自Apache的示例使用HttpClient。我看到发送了两个请求。 首先是带有响应401的初始请求和表示使用WWW-Authenticate: Negotiate(预期)的标题。然后,使用Authenticate标头和令牌发送第二个请求。然后,服务器以另一个401响应,并且它在标头中有自己的身份验证令牌。

当我尝试通过curl --negotiate发出相同的请求时,我看到了同样的行为,除了curl然后发送第三个请求,其中包含最终成功的修改后的令牌。

Apache tutorial可以这样说:

  

如果需要更多处理,则返回另一个HTTP 401   客户端在WWW-Authenticate标头中包含更多数据。客户需要   信息并生成另一个令牌,将其传回   授权标题直到完成。

这意味着这是可以发生的正常事情,但没有解释它会做什么。

如何通过HttpClient进行身份验证(或者如果有一种不同的方式,我也可以使用不同的库来更轻松地进行身份验证)。我的代码基于HttpClient的示例,如下所示。

public class ClientKerberosAuthentication {
    public static void main(String[] args) throws Exception {
        System.setProperty("java.security.auth.login.config", "login.conf");
        System.setProperty("java.security.krb5.conf", "krb5.conf");
        System.setProperty("sun.security.spnego.debug", "true");
        System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
        DefaultHttpClient httpclient = new DefaultHttpClient();
        try {
            Credentials use_jaas_creds = new Credentials() {
                public String getPassword() {
                    return null;
                }
                public Principal getUserPrincipal() {
                    return null;
                }
            };
            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(null, -1, null),
                    use_jaas_creds);
            HttpUriRequest request =
                    RequestBuilder.post("http://webservice")
                    .setEntity(EntityBuilder.create().setFile(new File("data.txt")).build())
                    .build();
            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();
            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            System.out.println("----------------------------------------");
            if (entity != null) {
                System.out.println(EntityUtils.toString(entity));
            }
            System.out.println("----------------------------------------");
            EntityUtils.consume(entity);
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    }
}

0 个答案:

没有答案