gpt4 book ai didi

java - HttpClient 为 Kerberos 身份验证设置凭据

转载 作者:太空狗 更新时间:2023-10-29 22:45:34 26 4
gpt4 key购买 nike

我正在尝试使用 kerberos/HTTP 主机进行身份验证。使用 Apache HttpClient 作为我的客户端 - 以及 this source. 的略微修改版本我的 Kerberos 身份验证非常顺利,我想知道如何以编程方式设置登录凭据。目前,凭据是通过控制台手动输入的,但我希望在运行时由我选择它。 [ 实际上,我希望对具有大量用户的服务器进行自动化和负载测试。 ].

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

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

接口(interface) Credentials 有两个方法 - getPassword()getUserPrincipal(),但从我进行的一些调试来看,它们没有似乎完全被调用了。

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

一个很similar question had been asked before ,但是 keytabs/login.conf hack 太麻烦了,对于具有大量用户凭据的自动负载测试来说不是一个实用的选择。感谢对此的任何帮助。

最佳答案

由于 SPNEGO,httpclient 未使用您发布的代码片段(Credentials 类内容设置)进行身份验证。

您可以使用 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<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

调查问题。

关于java - HttpClient 为 Kerberos 身份验证设置凭据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21629132/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com