【问题标题】:GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)GSSException:未提供有效凭据(机制级别:未能找到任何 Kerberos tgt)
【发布时间】:2015-11-20 14:22:42
【问题描述】:

我对 MMongoDB + Java 配置非常陌生。我正在尝试从 Java 应用程序实现与远程 mongodb 服务器的连接。我想使用 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) 在 sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:147) 在 sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122) 在 sun.security.jgss.GSSManagerImpl.getCredentialElement(GSSManagerImpl.java:193) 在 sun.security.jgss.GSSCredentialImpl.add(GSSCredentialImpl.java:427) 在 sun.security.jgss.GSSCredentialImpl.(GSSCredentialImpl.java:62) 在 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)

【问题讨论】:

  • 我对 MongoDB 一无所知,但该错误消息意味着 GSSAPI 认为您想使用 Kerberos 协议——是真的吗?如果是,您是否提供了配置来告诉 GSSAPI 如何联系 Kerberos 服务器?以及 (a) 缓存现有 Kerberos 票证的位置,或者 (b) 如何找到密码并即时创建票证?顺便说一句,如果您使用 Sun/Oracle JVM,您是否下载了“无限强度加密”策略 JAR 以启用 AES256 加密?
  • 是的,我想使用 Kerberos 协议。我设置了两个系统环境变量 1. KRB5_CONFIG=krb5.conf 2.KRB5_KTNAME=username.keytab 这就是我为配置视角所做的。我正在从 Java Web 应用程序访问这个 mongodb 服务器。希望我能够回答您的问题。
  • 查看stackoverflow.com/questions/21375372/… 了解设置 Kerberos conf 的肮脏细节(好吧,一些细节)
  • 加上一个有用的跟踪标志来解决配置问题:-Djava.security.debug=gssloginconfig,configfile,configparser,logincontext

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


【解决方案1】:

感谢所有回复并查看我的问题的人。

添加一些系统属性和一个新的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;};

我发布的代码对我有用。希望这对其他人有用。

【讨论】:

    【解决方案2】:

    在这篇文章中添加一些信息,因为它已经非常有用了。

    如果Sasl/createSaslClient 没有在Subject:doAs 方法中运行 从LoginContext 检索到的凭据将不会从krb5.conf 文件中提取。即GSS 代码查看通过Subject:doAs 方法注册的当前线程的主题安全管理器,然后使用来自该主题的凭据。这个Subject 应该是通过jaas 获得的,这反过来会读取正确的jaaskrb5.conf 凭据,但是如果你不运行saslsaslclient 方法内的Subject:doAs 方法这一切都无所谓。

    您可以通过设置javax.security.auth.useSubjectCredsOnly=false 来绕过它,这意味着如果找不到凭据,则会在 jaas 文件中搜索一些默认名称,参见LoginConfigImpl.java#92,一个是com.sun.security.jgss.initiate

    例如

    com.sun.security.jgss.initiate{
       com.sun.security.auth.module.Krb5LoginModule required
       doNotPrompt=true
       useTicketCache=true
       useKeyTab=true
       keyTab="mykeytab"
       principal="service/host@REALM";
     };
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的错误“机制级别:找不到任何 Kerberos tgt”。我的问题看起来与你的不同,但它可能对其他有相同错误的问题有用。

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

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

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

      【讨论】:

        猜你喜欢
        • 2020-04-02
        • 1970-01-01
        • 2019-10-02
        • 2022-11-10
        • 2015-11-19
        • 1970-01-01
        • 1970-01-01
        • 2012-08-29
        • 2020-04-14
        相关资源
        最近更新 更多