异常 - 使用 spnego-Kerberos IWA 在 Kerberos 数据库 (6) 中找不到客户端

问题描述 投票:0回答:2

我收到 SPNEGO/Kerberos 身份验证的以下错误

当我运行 HelloKeyTab.java 文件时出现此错误。

***Exception in thread "main" javax.security.auth.login.LoginException: Client not
found in Kerberos database (6)**
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(K
b5LoginModule.java:763)
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.j
va:584)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl
java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcce
sorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:762)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:
03)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:
87)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:595)
        at net.sourceforge.spnego.SpnegoHttpURLConnection.<init>(SpnegoHttpURLC
nnection.java:207)
        at HelloKeytab.main(HelloKeytab.java:17)
Caused by: KrbException: Client not found in Kerberos database (6)
        at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:76)
        at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:319)
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:364)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(K
b5LoginModule.java:735)
        ... 14 more
Caused by: KrbException: Identifier doesn't match expected value (906)
        at sun.security.krb5.internal.KDCRep.init(KDCRep.java:143)
        at sun.security.krb5.internal.ASRep.init(ASRep.java:65)
        at sun.security.krb5.internal.ASRep.<init>(ASRep.java:60)
        at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:60)
        ... 17 more*



我用于 SPNEGO/Kerberos 身份验证的设置、链接和文件。
链接- http://spnego.sourceforge.net/
tomcat服务器的域帐户
用户 - xyztest
密码 - ****
主体 - princ HTTP/[email protected]
1)HelloKeyTab.java - 为 apache tomcat 服务器生成的测试 keytab

    public class HelloKeytab {

    public static void main(final String[] args) throws Exception {
        System.setProperty("java.security.krb5.conf", "krb5.conf");
        System.setProperty("sun.security.krb5.debug", "true");
        System.setProperty("java.security.auth.login.config", "login.conf");

        SpnegoHttpURLConnection spnego = null;

        try {
           System.out.println("11111111");
            spnego = new SpnegoHttpURLConnection("custom-client");
            spnego.connect(new URL("http://localhost:8080/DemoAuth/hello_spnego.jsp"));
            System.out.println("2222222");   
            System.out.println("HTTP Status Code: " 
                    + spnego.getResponseCode());

            System.out.println("HTTP Status Message: "
                    + spnego.getResponseMessage());

        } finally {
            if (null != spnego) {
                spnego.disconnect();
            }
        }
    }
}

2)krb5.conf - Kerberos 配置文件

 [libdefaults]
        default_tkt_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-    hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5 
        default_tgt_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5 
       permitted_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5
       default_domain = CORP.XYZ.COM

    [realms]
         CORP.XYZ.COM  = {
               kdc = CORP.XYZ.COM
               default_domain = CORP.XYZ.COM 
    }

    [domain_realm]
         CORP.XYZ.COM = CORP.XYZ.COM

3)login.conf - 登录配置文件

    custom-client {
    com.sun.security.auth.module.Krb5LoginModule required
    storeKey=true
    useKeyTab=true
    keyTab="C:/apache-tomcat-7.0.40-windows-x64/apache-tomcat-7.0.40/bin/xyztest.keytab"
    principal="HTTP/[email protected]";
};
spnego-client {
     com.sun.security.auth.module.Krb5LoginModule required;
};
spnego-server {
    com.sun.security.auth.module.Krb5LoginModule required
    storeKey=true
    useKeyTab=true
    keyTab="C:/apache-tomcat-7.0.40-windows-x64/apache-tomcat-7.0.40/bin/xyztest.keytab"
    principal="HTTP/[email protected]";
};

4)setspn 命令 - 注册主体

setspn -s HTTP/APPSERVER1 xyztest
Checking domain DC=corp,DC=xyz,DC=com

Registering ServicePrincipalNames for CN=xyztest,CN=Users,DC=corp,DC=xyz,DC=com
       HTTP/APPSERVER1
Updated object

PS C:\Windows\system32> setspn -s HTTP/APPSERVER1.corp.xyz.com xyztest
Checking domain DC=corp,DC=xyz,DC=com

Registering ServicePrincipalNames for CN=xyztest,CN=Users,DC=corp,DC=xyz,DC=com
       HTTP/APPSERVER1.corp.xyz.com
Updated object

5)ktpass 命令:生成 keytab 文件

    ktpass /princ HTTP/[email protected] /mapuser xyztest /pass ***** /out xyztest.keytab /crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL
Targeting domain controller: xyzDC1.corp.xyz.com
Using legacy password setting method
ktpass : Successfully mapped HTTP/APPSERVER1 to xyztest.
At line:1 char:1
+ ktpass /princ HTTP/[email protected] /mapuser xyztest /pass *****
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Successfully ma...o xyztest.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Key created.
Output keytab to xyztest.keytab:
Keytab version: 0x502
keysize 84 HTTP/[email protected] ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x12 (AES256-SHA1) keylength 32 
(0x6e6afbbefc78946121bd7ed6657524c7409917cae1708223ce938449113d9805)

6)Apache tomcat 服务器
7)JDK 7
8) 域控制器 - Windows Active Directory
9)如果我尝试运行 kinit 命令来使用 keytab 验证主体,我会得到相同的错误 Client not found in Kerberos database (6)

    Command - kinit -k -t xyztest.keytab HTTP/[email protected]
Result - Exception krb_error 6 client not found in kerberos database (6)

10)HelloKDC.java :链接 http://spnego.sourceforge.net/ 提供 HelloKDC.java 来测试与 KDC 的连接。我可以使用 HelloKDC.java 成功连接到 KDC

    public final class HelloKDC {

    private HelloKDC() {
        // default private
    }

    public static void main(final String[] args) throws Exception {

        // Domain (pre-authentication) account
        final String username = "xyztest";

        // Password for the pre-auth acct.
        final String password = "!Dragonfly1!";

        // Name of our krb5 config file
        final String krbfile = "krb5.conf";

        // Name of our login config file
        final String loginfile = "login.conf";

        // Name of our login module
        final String module = "spnego-client";

        // set some system properties
        System.setProperty("java.security.krb5.conf", krbfile);
        System.setProperty("java.security.auth.login.config", loginfile);
        //System.setProperty("sun.security.krb5.debug", true);

        // assert 
        HelloKDC.validate(username, password, krbfile, loginfile, module);

        final CallbackHandler handler = 
            HelloKDC.getUsernamePasswordHandler(username, password);

        final LoginContext loginContext = new LoginContext(module, handler);

        // attempt to login
        loginContext.login();

        // output some info
        System.out.println("Subject=" + loginContext.getSubject());

        // logout
        loginContext.logout();

        System.out.println("Connection test successful.");
    }

    private static void validate(final String username, final String password
        , final String krbfile, final String loginfile, final String moduleName) 
        throws FileNotFoundException, NoSuchAlgorithmException {

        // confirm username was provided
        if (null == username || username.isEmpty()) {
            throw new IllegalArgumentException("Must provide a username");
        }

        // confirm password was provided
        if (null == password || password.isEmpty()) {
            throw new IllegalArgumentException("Must provide a password");
        }

        // confirm krb5.conf file exists
        if (null == krbfile || krbfile.isEmpty()) {
            throw new IllegalArgumentException("Must provide a krb5 file");
        } else {
            final File file = new File(krbfile);
            if (!file.exists()) {
                throw new FileNotFoundException(krbfile);
            }
        }

        // confirm loginfile
        if (null == loginfile || loginfile.isEmpty()) {
            throw new IllegalArgumentException("Must provide a login file");
        } else {
            final File file = new File(loginfile);
            if (!file.exists()) {
                throw new FileNotFoundException(loginfile);
            }
        }

        // confirm that runtime loaded the login file
        final Configuration config = Configuration.getConfiguration();

        // confirm that the module name exists in the file
        if (null == config.getAppConfigurationEntry(moduleName)) {
            throw new IllegalArgumentException("The module name " 
                    + moduleName + " was not found in the login file");
        }        
    }

    private static CallbackHandler getUsernamePasswordHandler(
        final String username, final String password) {

        final CallbackHandler handler = new CallbackHandler() {
            public void handle(final Callback[] callback) {
                for (int i=0; i<callback.length; i++) {
                    if (callback[i] instanceof NameCallback) {
                        final NameCallback nameCallback = (NameCallback) callback[i];
                        nameCallback.setName(username);
                    } else if (callback[i] instanceof PasswordCallback) {
                        final PasswordCallback passCallback = (PasswordCallback) callback[i];
                        passCallback.setPassword(password.toCharArray());
                    } else {
                        System.err.println("Unsupported Callback: " 
                                + callback[i].getClass().getName());
                    }
                }
            }
        };

        return handler;
    }
}

请向我提供解决方案来解决该错误
在 Kerberos 数据库中找不到客户端 (6)

klist输出

    #0>     Client: xyztest @ CORP.XYZ.COM
        Server: krbtgt/CORP.XYZ.COM @ CORP.XYZ.COM
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent n
ame_canonicalize
        Start Time: 3/8/2017 10:01:14 (local)
        End Time:   3/8/2017 20:01:14 (local)
        Renew Time: 3/15/2017 10:01:14 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0x2 -> DELEGATION
        Kdc Called: xyzDC1.corp.xyz.com

#1>     Client: xyztest @ CORP.XYZ.COM
        Server: krbtgt/CORP.XYZ.COM @ CORP.XYZ.COM
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40e10000 -> forwardable renewable initial pre_authent nam
e_canonicalize
       Start Time: 3/8/2017 10:01:14 (local)
        End Time:   3/8/2017 20:01:14 (local)
        Renew Time: 3/15/2017 10:01:14 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0x1 -> PRIMARY
        Kdc Called: xyzDC1.corp.xyz.com

#2>     Client: xyztest @ CORP.XYZ.COM
        Server: ldap/xyzDC1.corp.xyz.com @ CORP.XYZ.COM
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_deleg
ate name_canonicalize
        Start Time: 3/8/2017 10:01:16 (local)
        End Time:   3/8/2017 20:01:14 (local)
        Renew Time: 3/15/2017 10:01:14 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0
        Kdc Called: xyzDC1.corp.xyz.com

#3>     Client: xyztest @ CORP.XYZ.COM
        Server: LDAP/xyzDC1.corp.xyz.com/corp.xyz.com @ CORP.ADAP
TIVE.COM
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_deleg
ate name_canonicalize
        Start Time: 3/8/2017 10:01:15 (local)
        End Time:   3/8/2017 20:01:14 (local)
        Renew Time: 3/15/2017 10:01:14 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0
        Kdc Called: xyzDC1.corp.xyz.com

#4>     Client: xyztest @ CORP.XYZ.COM
        Server: cifs/xyzDC1.corp.xyz.com @ CORP.XYZ.COM
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_deleg
ate name_canonicalize
        Start Time: 3/8/2017 10:01:14 (local)
        End Time:   3/8/2017 20:01:14 (local)
        Renew Time: 3/15/2017 10:01:14 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0
        Kdc Called: xyzDC1.corp.xyz.com
kerberos spnego
2个回答
1
投票

在 Kerberos 环境中工作时请记住以下事项

  1. 创建 keytab 文件时以及在任何地方使用 Realm 时,Realm(域名)应为大写
  2. 对于 SPNEGO 身份验证,每个服务器主机应映射为 Web 身份验证用户的 HTTP/主机名。例如,

    setspn -s HTTP/主机名 xyztest

  3. Kerberos 票证应在每个操作的环境 krb5ccname 中可用

使用用户名和密码获取 Kerberos 票证

kinit principal password

使用密钥表获取 Kerberos 票证

kinit -k -t keytab principal

您可以使用环境变量 krb5ccname 设置票证位置

set krb5ccname=newticketfilelocation

要列出票证详细信息,请将目录更改为 java 并运行

klist
。这是因为 klist 命令在 Windows 中可用,并且它仅显示登录的用户票证。要列出从 kinit 命令获取的票证,您应该从位置中的 java 运行

klist

0
投票

仅供参考,我面临着同样的问题,但找不到有关以下例外情况的任何澄清信息:

Caused by: KrbException: Client not found in Kerberos database (6)
        ... 
Caused by: KrbException: Identifier doesn't match expected value (906)

当在 AD 中找不到用于使用 Kerberos 进行身份验证的主体时,会抛出

Client not found in Kerberos database (6)
。因此,我建议:

  • 检查主体是否在 AD 中创建;
  • 验证“principal”的值没有拼写错误;
  • 验证用于身份验证的领域(域)是否是创建主体的领域。

就我的具体情况而言,这是由于校长的拼写错误造成的。

© www.soinside.com 2019 - 2024. All rights reserved.