GSSException:未提供有效凭据(机制级别:无法找到任何Kerberos tgt)

时间:2015-11-20 14:22:43

标签: java spring mongodb spring-mvc spring-security-kerberos

我是MOngoDB + Java配置的新手。我试图从远程mongodb服务器到Java应用程序的连接。我想使用GSSAPI机制来连接mongotemplate。下面的代码已成功执行。下面的代码来自我的配置文件。

List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();
    ServerAddress address = new ServerAddress(host, port);
    serverAddresses.add(address);
    List<MongoCredential> credentials = new ArrayList<MongoCredential>();

    MongoCredential credential = MongoCredential.createGSSAPICredential(userName);

    credential.withMechanismProperty("SERVICE_NAME", gssapiServiceName);
    credential.withMechanismProperty("CANONICALIZE_HOST_NAME", true);
    credentials.add(credential);

    return new MongoClient(serverAddresses, credentials);

但是当我尝试执行下面的代码时,我得到了异常

DB db = mongoTemplate.getDb();
Set<String> dbCollections1 = db.getCollectionNames();

例外:

  

GSSException:未提供有效凭据(机制级别:无法找到任何Kerberos tgt)       at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:147)       at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)       at sun.security.jgss.GSSManagerImpl.getCredentialElement(GSSManagerImpl.java:193)       at sun.security.jgss.GSSCredentialImpl.add(GSSCredentialImpl.java:427)       在sun.security.jgss.GSSCredentialImpl。(GSSCredentialImpl.java:62)       at sun.security.jgss.GSSManagerImpl.createCredential(GSSManagerImpl.java:154)       在com.mongodb.DBPort $ GSSAPIAuthenticator.getGSSCredential(DBPort.java:622)       在com.mongodb.DBPort $ GSSAPIAuthenticator.createSaslClient(DBPort.java:593)       在com.mongodb.DBPort $ SaslAuthenticator.authenticate(DBPort.java:895)       在com.mongodb.DBPort.authenticate(DBPort.java:432)       在com.mongodb.DBPort.checkAuth(DBPort.java:443)       在com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:289)       在com.mongodb.DBTCPConnector.call(DBTCPConnector.java:269)       在com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:84)       在com.mongodb.DB.command(DB.java:320)       在com.mongodb.DB.command(DB.java:299)       在com.mongodb.DB.command(DB.java:388)       在com.mongodb.DBApiLayer.getCollectionNames(DBApiLayer.java:152)

3 个答案:

答案 0 :(得分:10)

万分感谢所有回复并回顾我问题的人。

添加一些系统属性和新的conf文件后,最后我能够与MongoDB服务器连接。这里有更新的代码 -

try {
        System.setProperty("java.security.krb5.conf","C:/mongodb/UnixKeytab/krb5.conf");
        System.setProperty("java.security.krb5.realm","EXAMPLE.COM");
        System.setProperty("java.security.krb5.kdc","example.com");
        System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
        System.setProperty("java.security.auth.login.config","C:/mongodb/UnixKeytab/gss-jaas.conf");


        List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();
        ServerAddress address = new ServerAddress(host, port);
        serverAddresses.add(address);
        List<MongoCredential> credentials = new ArrayList<MongoCredential>();
        MongoCredential credential = MongoCredential.createGSSAPICredential(username);
        credentials.add(credential);
        MongoClient mongoClient1 = new MongoClient(serverAddresses, credentials);
        DB db = mongoClient1.getDB(database);

    } catch (UnknownHostException e) {
        e.printStackTrace();
    }

我的krb5.conf文件如下所示 -

[libdefaults]
     default_realm = EXAMPLE.COM
     default_tkt_enctypes = des-cbc-md5 rc4-hmac
     default_tgs_enctypes = des-cbc-md5 rc4-hmac
     default_keytab_name = <keytab file path>
[realms]
EXAMPLE.COM = {
    kdc = example.com
    master_kdc = example.com
    default_domain = EXAMPLE.COM
}
INTRANET = {
    kdc = example.com
    master_kdc = example.com
    default_domain = example.com
}

我的gss-jaas.conf如下所示 -

com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
useTicketCache=false
principal="my-account@MY_REALM"
doNotPrompt=true
keyTab="path-to-my-keytab-file"
debug=true;};

我发布的代码正在为我工​​作。希望这对其他人有用。

答案 1 :(得分:2)

在这篇文章中添加一些非常有用的信息。

如果Sasl/createSaslClient未在Subject:doAs方法中运行 从LoginContext检索到的凭据将不会从krb5.conf文件中获取凭据。即,GSS代码查看通过Subject:doAs方法注册的主题的当前线程的安全管理器,然后使用此主题的凭据。这个Subject应该是通过jaas获得的,而jaas反过来会读取正确的krb5.confsasl凭据,但如果您没有运行saslclient和所有这些都与Subject:doAs方法中的javax.security.auth.useSubjectCredsOnly=false方法无关。

您可以通过设置com.sun.security.jgss.initiate来解决这个问题,这意味着如果找不到凭据,则会搜索jaas文件中的一些默认名称,以查看LoginConfigImpl.java#92,其中一个是com.sun.security.jgss.initiate{ com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=true useTicketCache=true useKeyTab=true keyTab="mykeytab" principal="service/host@REALM"; };

e.g

rsa.PublicKey

答案 2 :(得分:1)

我遇到了同样的错误&#34;机制级别:找不到任何Kerberos tgt&#34;。我的问题与你的问题有所不同,但对于具有相同错误的其他问题可能会有用。

在我的情况下,它是由我在其中一个配置文件中写入主体名称时出错。

我建议检查Jaas LoginManager配置文件(随java.security.auth.login.config提供)和主体的策略文件。典型错误是小写的域名:gino@authdemo.it而不是gino@AUTHDEMO.IT

如果以编程方式设置/引用主体,还可以检查代码中的主体名称正确性。 此致