当前位置: 首页 > 知识库问答 >
问题:

无法使用Kerberos Keytab和kinit缓存进行身份验证

邢财
2023-03-14

我正在使用一个keytab,并使用windows命令行上的kinit命令设置它。我得到消息“new ticket is storage in cache file”。之后,当我运行java应用程序访问keytab文件以获取密钥时,我得到以下错误。

Authentication attempt failed javax.security.auth.login.LoginException: No key to store
javax.security.auth.login.LoginException: No key to store
    at com.sun.security.auth.module.Krb5LoginModule.commit(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)
-Djavax.security.auth.useSubjectCredsOnly=false
-Djava.security.auth.login.config=C:\Users\cXXXXXX\Git\gssapi_jaas.conf
-Dsun.security.krb5.debug=true

C:\users\cxxxxx\git\abcd.keytab refreshKrb5Config为false主体为xxxx_dev@xxxx.xxxxx.com tryFirstPass为false useFirstPass为false storePass为false clearPass为false从缓存获取TGT

KinitOptions缓存名为C:\users\cxxxxxx\krb5cc_cxxxxxxx调试客户端主体为xxxx_dev@xxxx.xxxxx.com调试服务器主体为krbtgt/xxxx.xxxxx.com@txxxx.xxxxx.com调试密钥类型:23调试时间:Mon Jul 01 14:20:21 EDT 2019调试开始时间:Mon Jul 01 14:20:21 EDT 2019调试结束时间:Tue Jul 02 00:20:21 EDT 2019调试更新时间:null ccacheinputstream:readFlags()初始;Pre_Auth;主机地址为/xx.xx.xxx.xxx.xx主机地址为/xxx:0:0:0:xxxx:xxxx:xxxxkrbcreds在凭据缓存中找到默认票据授予票据。Java配置名称:null本机配置名称:C:\windows\krb5.ini从lsa获得TGT:credentials:client=sxxxx_dev@xxxx.xxxxx.com server=krbtgt/txxx.xxxxx.com@txxxx.xxxxx.com authtime=20190701182021z starttime=20190701182021z endtime=20190702042021z renewtil=null flags=initial;pre-authent EType(skey)=23(tkt key)=18主体是

在添加kinit缓存fill之前,我至少能够验证帐户,然后我遇到了GSSapi安全性问题。试图解决我添加的缓存和这个新的问题开始发生

public static void main(String[] args) {

    // 1. Log in (to Kerberos)
    LoginContext lc = null;
    try {
        /*lc = new LoginContext(Azrm017.class.getName(),
        new LuwCallBackHandler());
*/
        lc = new LoginContext("Azrm017");
        // Attempt authentication
        // You might want to do this in a "for" loop to give
        // user more than one chance to enter correct username/password
        lc.login();

    } catch (LoginException le) {
        System.err.println("Authentication attempt failed " + le);
        le.printStackTrace();
        System.err.println("Authentication attempt failed " + le.getSuppressed());

        System.exit(-1);
    }

    // 2. Perform JNDI work as logged in subject
    NamingEnumeration<SearchResult> ne =
            (NamingEnumeration<SearchResult>) Subject.doAs(lc.getSubject(),
                new SearchAction());
    while(ne.hasMoreElements()) {
        System.out.println(">>>> : " + ne.nextElement().getName());
    }

    //Subject.doAs(lc.getSubject(), new JndiAction(args));
    }
}


/**
 * The application must supply a PrivilegedAction that is to be run
 * inside a Subject.doAs() or Subject.doAsPrivileged().
 */
class SearchAction implements java.security.PrivilegedAction {

    public Object run() {

        // Set up the environment for creating the initial context
        Hashtable<String, String> env = new Hashtable<> (11);
        env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
        String cn = "dn:CN=xxxxxxx,OU=Service xxxxx,OU=Accounts,OU=xxxxx,DC=test,DC=xxxxxx,DC=com";
        env.put(Context.PROVIDER_URL, "ldap://test.xxxxxxx.com:389");
        env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
        env.put("javax.security.sasl.server.authentication", "true");
        env.put("javax.security.sasl.qop", "auth-conf");

        DirContext ctx = null;
        try {
           // Create initial context
           ctx = new InitialDirContext(env);

           SearchControls ctls = new SearchControls();
           ctls.setReturningAttributes(
                 new String[] {"displayName", "mail","description", "suSunetID"});

           NamingEnumeration<SearchResult> answer =
                ctx.search("cn=People, dc=test, dc=xxxxxxxx, dc=com",
                                 "(&(cn=p*)(sn=s*))", ctls);

            return answer;


        } catch (Exception e) {
               e.printStackTrace();
        }
         // Close the context when we're done
        finally {
            closeContext(ctx);
        }
        return null;
    }

附上

共有1个答案

衡玄裳
2023-03-14

这是Krb5LoginModule选项的错误组合。如果希望发起者存储密钥,则必须使用该密钥获取票证(即,useTicketCache不应为true)。

为什么要存储钥匙?发起者是否也会充当接受者?如果是,则应该使用keytab进行身份验证(即useticketcache=false),或者使用ENC-TKT-IN-SKEY方式(即storekey=false)。

 类似资料:
  • 问题内容: 我正在尝试使用swift来对本地播放器进行身份验证,但是每次我为.authenticated属性获取错误值时,都无法使用。这是我正在使用的代码,应用启动时,主视图控制器会调用它。 它可以很好地显示登录视图,但是当我输入测试帐户登录名时,它只是将as 返回为false。iTunes Connect中的捆绑包标识符和info.plist完全相同,版本和应用程序名称也相同。iTunes Co

  • 问题内容: 我想为在Raspberry Pi上运行并像本地服务器一样工作的软件制作一些更新脚本。该服务器应连接到Web上的主服务器,以获取软件更新并验证软件的许可证。为此,我设置了两个python脚本。我希望它们通过TLS套接字连接。然后,客户端检查服务器证书,然后服务器检查它是否是授权的客户端之一。我在此页面上找到了解决方案。 现在还有一个问题。我想知道 哪个客户端 (取决于证书)正在建立连接。

  • 但请求呢?和是用户的属性,但应将它们发送到endpoint。如果我将资源发送到endpoint,则没有多大意义。 对此有没有办法,遵循JSONAPI并保持API的意义?

  • 我正在尝试使用urllib3连接到网页。代码如下所示。 如果我们假设url是需要使用用户名和密码进行身份验证的某个网页,那么我是否使用正确的代码进行身份验证? 我使用urllib2做这件事很舒服,但使用urllib3做不到同样的事情。 非常感谢

  • jwt不应该仅仅用于认证用户吗?我读到过可以在里面存储非敏感的东西,比如用户ID。将权限级别之类的东西存储在令牌中可以吗?这样我可以避免数据库调用。

  • 我尝试在Azure门户上创建的O365应用程序上进行身份验证,但它没有按预期工作。 以下代码运行良好,但它使用的是登录/密码,Microsoft不推荐使用。(在此处找到https://github.com/jstedfast/MailKit/issues/989) 事实上,我希望能够使用tenanid、客户端机密和clientid进行身份验证,但没有交互模式(因为该应用程序是Windows服务)。