使用java驱动程序使用kerberos连接到cassandra集群

时间:2014-02-11 04:54:27

标签: cassandra kerberos datastax-enterprise datastax

我按照以下数据广告发布的说明 - Accessing secure DSE clusters

这是我的代码段 -

public static void main(String[] args) {
KerberosAuthenticatedClient client = new KerberosAuthenticatedClient();     
System.setProperty("java.security.krb5.conf","C:/Users/ADMIN/Desktop/krb5.config");
System.setProperty("java.security.auth.login.config","C:/Users/ADMIN/Desktop/DseClient.config");    
cluster = Cluster.builder().addContactPoint(node).withAuthProvider(new DseAuthProvider()).build();
session = cluster.connect();

这是我的DseClient文件 -

DseClient {
    com.sun.security.auth.module.Krb5LoginModule required
     useKeyTab=true
   doNotPrompt=true
     keyTab="C:/Users/ADMIN/Desktop/dse.keytab"
     principal="rock@MY.COM";
};

这是我的krb5.conf -

[libdefaults]
default_realm = MY.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true

[realms]
MY.COM = {
kdc = x.x.x.x
admin_server = x.x.x.x
}

[domain_realm]
.my.com = MY.COM
my.com = MY.COM

我已在客户端计算机上安装了kerberos,也在服务器上安装了kerberos。但是当我跑步时,我得到以下错误: -

Exception in thread "main" java.lang.RuntimeException: javax.security.auth.login.LoginException: Unable to obtain password from user

at com.datastax.driver.core.sasl.KerberosAuthenticator.loginSubject(KerberosAuthenticator.java:113)
at com.datastax.driver.core.sasl.KerberosAuthenticator.<init>(KerberosAuthenticator.java:94)
at com.datastax.driver.core.sasl.DseAuthProvider.newAuthenticator(DseAuthProvider.java:52)
at com.datastax.driver.core.Connection.initializeTransport(Connection.java:163)
at com.datastax.driver.core.Connection.<init>(Connection.java:131)
at com.datastax.driver.core.Connection.<init>(Connection.java:59)
at com.datastax.driver.core.Connection$Factory.open(Connection.java:444)
at com.datastax.driver.core.ControlConnection.tryConnect(ControlConnection.java:205)
at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:168)
at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:81)
at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:812)
at com.datastax.driver.core.Cluster$Manager.access$100(Cluster.java:739)
at com.datastax.driver.core.Cluster.<init>(Cluster.java:82)
at com.datastax.driver.core.Cluster.<init>(Cluster.java:67)
at com.datastax.driver.core.Cluster$Builder.build(Cluster.java:708)
at KerberosAuthenticatedClient.connect(KerberosAuthenticatedClient.java:19)
at KerberosAuthenticatedClient.main(KerberosAuthenticatedClient.java:45)
Caused by: javax.security.auth.login.LoginException: Unable to obtain password from user

at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Unknown Source)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Unknown Source)
at com.sun.security.auth.module.Krb5LoginModule.login(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.security.auth.login.LoginContext.invoke(Unknown Source)
at javax.security.auth.login.LoginContext.access$000(Unknown Source)
at javax.security.auth.login.LoginContext$4.run(Unknown Source)
at javax.security.auth.login.LoginContext$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
at javax.security.auth.login.LoginContext.login(Unknown Source)
at com.datastax.driver.core.sasl.KerberosAuthenticator.loginSubject(KerberosAuthenticator.java:109)
... 16 more

2 个答案:

答案 0 :(得分:2)

stacktrace中的错误是抱怨它无法找到执行请求的OS用户的任何凭据。这通常是由以下三个条件之一引起的:

  1. 未正确设置JAAS配置的位置(这导致我们回退到使用TGT缓存的默认值,通常导致2。)
  2. 空的本地票证缓存(不使用密钥表时)
  3. 密钥表中缺少指定主体的凭据
  4. 我要检查的第一件事是您已将java.security.auth.login.config系统属性设置为JAAS配置文件(DseClient文件)的位置吗? 如果您已经并且仍然看到错误,则可以使用klist -e -t -k /path/to/keytab

    检查密钥表的内容

    另一个有用的调试技巧是设置-Dsun.security.krb5.debug=true,它会将大量详细信息转储到stdout。

答案 1 :(得分:0)

我将服务原则从cassandra / hostname @ REALM更改为dse / hostname @ REALM并且它有效。我不确定为什么从我的Windows机器运行的java程序将服务原则作为dse / hostname而不是cassandra / hostname