Kerberos/HTTPホストで認証しようとしています。クライアントとしてApache HttpClientを使用する- このソースを少し変更したバージョン。 私の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);
..
_
インターフェイスCredentials
にはgetPassword()
とgetUserPrincipal()
の2つのメソッドがありますが、私が行ったいくつかのデバッグから、それらはまったく呼び出されていないようです。
ここで何が欠けていますか?資格情報を静的に設定するよりクリーンな方法は何ですか?
非常に 似たような質問が以前に行われました が、keytabs/login.confハックは面倒で、大規模な自動負荷テストの実用的なオプションではありませんユーザー資格情報の数。これに関するどんな助けにも感謝します。
SPNEGOのため、投稿したスニペットコード(Credentialsクラスの設定)は、httpclientによる認証には使用されません。
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用に正しく構成されている場合、このクラスはそのまま機能します(適切なファイルlogin.confおよびkrb5.iniを使用)。httpclient4.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
問題を調査します。