HttpClient的设置Kerberos身份验证凭据 [英] HttpClient set credentials for Kerberos authentication

查看:2443
本文介绍了HttpClient的设置Kerberos身份验证凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用一个Kerberos / HTTP主机进行身份验证。使用Apache HttpClient的为我的客户 - 而略加修改<一个href=\"http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientKerberosAuthentication.java?p=820841\">this源。
我的Kerberos身份验证顺利完美罚款,我想知道如何编程设置登录凭据。目前,凭据通过控制台手动输入,但我想请有我在运行时选择。 [当我想自动化并加载了大量的用户测试服务器,其实。 ]。

I am trying to authenticate with a kerberos/HTTP host. Using Apache HttpClient as my client - and a slightly modified version of this source. My Kerberos authentication goes perfectly fine, and I wish to know how to set the login credentials programatically. At the moment, the credentials are entered manually through the console, but I want to have it chosen by me at run time. [ As I wish to automate and load test the server with a large number of users, actually. ].

编辑:下面是相关零件的code片断:

EDIT : Here is a code snippet of the relevant parts :

..
        NegotiateSchemeFactory nsf = new NegotiateSchemeFactory();        
        httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf);

        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 = new HttpGet("http://kerberoshost/");
        HttpResponse response = httpclient.execute(request);
 .. 

接口证书有两个方法 - getPassword来() getUserPrincipal(),但是从一些调试我这样做,他们似乎根本不被调用。

The interface Credentials has two methods - getPassword() and getUserPrincipal(), but from some debugging I did, they don't seem to be invoked at all.

我缺少的是在这里吗?什么是静态设置凭据一个更清洁的方式?

What am I missing here ? What is a cleaner way to statically set the credentials ?

一个非常<一个href=\"http://stackoverflow.com/questions/10923283/setting-username-programatically-instead-of-prompt-with-httpclient-kerberos\">similar问题还之前已经问过,但keytabs / login.conf的破解过于繁琐和具有大量用户凭证的自动化负载测试不是一个可行的选择。
鸭preciate有这方面的帮助。

A very similar question had been asked before, but keytabs/login.conf hack is too cumbersome and not a practical option for an automated load test with a large number of user credentials. Appreciate any help on this.

推荐答案

您发布的片断code(证书类的东西设置)不使用HttpClient的认证。

Because of SPNEGO the snippet code you post (Credentials class stuff setup) is not used by httpclient to authenticate.

您可以使用DOAS +一个的CallbackHandler传递用户放大器;密码在运行时。

You can use a DoAs + a CallBackhandler to pass user & password at runtime.

然后你需要一个login.conf中或任何名称以这里面:

Then you need a login.conf or whatever the name with this inside:

KrbLogin{
 com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false debug=true useTicketCache=false;
};

您可以从KrbLogin将名称更改为你喜欢的(还记得在你的java code使用相同的名称)的名称

You can change the name from "KrbLogin" to the name you like (remember to use the same name in your java code)

和设置该用java系统属性:

and set this with java system properties:

System.setProperty("java.security.auth.login.config", "login.conf");

或具有

-Djava.security.auth.login.config=login.config

然后你需要一个krb5的配置文件(通常krb5.ini或内部配置正确的krb5.conf)

Then you need a krb5 config file (usually krb5.ini or krb5.conf with correct configuration inside)

如果您的工作站(或服务器)正确配置为Kerberos此类应作品是(与propper文件login.conf中和krb5.ini)我用的HttpClient 4.3.3和Java 1.7来测试它:

If your workstation (or server) is properly configured for Kerberos this class should works as is (with propper file login.conf and krb5.ini) I used httpclient 4.3.3 and java 1.7 to test it:

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.impl.auth.SPNegoSchemeFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.io.IOException;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Set;

public class HttpClientKerberosDoAS {

    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("javax.security.auth.useSubjectCredsOnly", "false");

        String user = "";
        String password = "";
        String url = "";

        if (args.length == 3) {
            user = args[0];
            password = args[1];
            url = args[2];


            HttpClientKerberosDoAS kcd = new HttpClientKerberosDoAS();

            System.out.println("Loggin in with user [" + user + "] password [" + password + "] ");
            kcd.test(user, password, url);
        } else {
            System.out.println("run with User Password URL");
        }

    }

    public void test(String user, String password, final String url) {
        try {

            LoginContext loginCOntext = new LoginContext("KrbLogin", new KerberosCallBackHandler(user, password));
            loginCOntext.login();

            PrivilegedAction sendAction = new PrivilegedAction() {

                @Override
                public Object run() {
                    try {

                        Subject current = Subject.getSubject(AccessController.getContext());
                        System.out.println("----------------------------------------");
                        Set<Principal> principals = current.getPrincipals();
                        for (Principal next : principals) {
                            System.out.println("DOAS Principal: " + next.getName());
                        }
                        System.out.println("----------------------------------------");

                        call(url);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return true;
                }
            };

            Subject.doAs(loginCOntext.getSubject(), sendAction);

        } catch (LoginException le) {
            le.printStackTrace();
        }
    }

    private void call(String url) throws IOException {
        HttpClient httpclient = getHttpClient();

        try {

            HttpUriRequest request = new HttpGet(url);
            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");

            System.out.println("STATUS >> " + response.getStatusLine());

            if (entity != null) {
                System.out.println("RESULT >> " + EntityUtils.toString(entity));
            }

            System.out.println("----------------------------------------");

            EntityUtils.consume(entity);

        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    }

    private  HttpClient getHttpClient() {

        Credentials use_jaas_creds = new Credentials() {
            public String getPassword() {
                return null;
            }

            public Principal getUserPrincipal() {
                return null;
            }
        };

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(new AuthScope(null, -1, null), use_jaas_creds);
        Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create().register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true)).build();
        CloseableHttpClient httpclient = HttpClients.custom().setDefaultAuthSchemeRegistry(authSchemeRegistry).setDefaultCredentialsProvider(credsProvider).build();

        return httpclient;
    }

    class KerberosCallBackHandler implements CallbackHandler {

        private final String user;
        private final String password;

        public KerberosCallBackHandler(String user, String password) {
            this.user = user;
            this.password = password;
        }

        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

            for (Callback callback : callbacks) {

                if (callback instanceof NameCallback) {
                    NameCallback nc = (NameCallback) callback;
                    nc.setName(user);
                } else if (callback instanceof PasswordCallback) {
                    PasswordCallback pc = (PasswordCallback) callback;
                    pc.setPassword(password.toCharArray());
                } else {
                    throw new UnsupportedCallbackException(callback, "Unknown Callback");
                }

            }
        }
    }

}

请注意:

您可以使用:

System.setProperty("sun.security.krb5.debug", "true");

-Dsun.security.krb5.debug=true

在调查问题。

这篇关于HttpClient的设置Kerberos身份验证凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆