HttpClient为Kerberos身份validation设置凭据

我正在尝试使用kerberos / HTTP主机进行身份validation。 使用Apache HttpClient作为我的客户端 – 以及此源的略微修改版本。 我的Kerberos身份validation完全正常,我希望知道如何以编程方式设置登录凭据。 目前,凭据是通过控制台手动输入的,但我希望在运行时由我选择。 [实际上,我希望自动化并加载测试具有大量用户的服务器。 ]。

编辑:这是相关部分的代码片段:

.. 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); .. 

接口Credentials有两个方法 – getPassword()getUserPrincipal() ,但是从我做过的一些调试中,它们似乎根本没有被调用。

我在这里想念的是什么? 什么是静态设置凭据的更简洁方法?

之前曾经提出过一个非常类似的问题 ,但是keytabs / login.conf hack过于繁琐,并且对于使用大量用户凭据进行自动负载测试而言并不实用。 感谢任何帮助。

由于SPNEGO,您发布的代码段(凭据类设置)不会被httpclient用于身份validation。

您可以使用DoAs + CallBackhandler在运行时传递用户和密码。

然后你需要一个login.conf或其中的任何名称:

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

您可以将名称从“KrbLogin”更改为您喜欢的名称(请记住在Java代码中使用相同的名称)

并使用java系统属性设置:

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

或者用

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

然后你需要一个krb5配置文件(通常是krb5.ini或krb5.conf,里面有正确的配置)

如果您的工作站(或服务器)已正确配置为Kerberos,则此类应该按原样运行(使用propper文件login.conf和krb5.ini)我使用httpclient 4.3.3和java 1.7来测试它:

 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 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 authSchemeRegistry = RegistryBuilder.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 

调查问题。