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

时间:2017-03-06 13:19:32

标签: kerberos spnego

我收到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身份验证的设置,链接和文件 link- http://spnego.sourceforge.net/
tomcat服务器的域帐户
用户 - xyztest
密码 - ****
principal - princ HTTP /APPSERVER1@corp.xyz.com
1)HelloKeyTab.java - 为apache tomcat服务器生成的测试密钥表

    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 -Login配置文件

    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/APPSERVER1@corp.xyz.com";
};
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/APPSERVER1@corp.xyz.com";
};

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/APPSERVER1@corp.xyz.com /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/APPSERVER1@corp.xyz.com /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/APPSERVER1@corp.xyz.com ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x12 (AES256-SHA1) keylength 32 
(0x6e6afbbefc78946121bd7ed6657524c7409917cae1708223ce938449113d9805)
6)Apache tomcat服务器
 7)JDK 7
 8)域控制器 - Windows Active目录
 9)如果我尝试运行kinit命令来使用keytab对主体进行身份验证,我会得到相同的错误Kerberos数据库中找不到客户端(6)

    Command - kinit -k -t xyztest.keytab HTTP/APPSERVER1@corp.xyz.com
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

1 个答案:

答案 0 :(得分:1)

在处理Kerberos环境时,请牢记以下事项

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

    setspn -s HTTP / hostname xyztest

  3. Kerberos票证应该在每个操作的环境krb5ccname中可用
  4. 使用用户名和密码获取Kerberos票证

    kinit principal password
    

    使用keytab获取Kerberos票证

    kinit -k -t keytab principal
    

    您可以使用环境变量krb5ccname

    设置故障单位置
    set krb5ccname=newticketfilelocation
    

    要列出故障单详细信息,请将目录更改为java \ bin并运行klist。这是因为klist命令在Windows中可用,它只显示登录的用户票证​​。要列出从kinit命令获得的票证,您应该从java \ bin位置

    运行
    klist