2011-12-14 29 views
8

Kerberos/AD認証がSpring Webアプリケーションと連動するのに問題がありますが、問題はKerberosチケットとActive Directoryの暗号化タイプドメイン機能レベル。チェックサムが失敗しました:Kerberos/Spring/Active Directory(2008)

基本的な設定は次のとおりです。

私は1つen Active Directoryドメインの機能レベルがWindows Server 2003で、すべて正常に動作し、ドメインにログオンしているクライアントが期待通りに認証されます。この環境でkerbtrayを使用してチケットを調べると、チケット暗号化タイプとキー暗号化タイプ「RSADSI RC4-HMAC」の両方があることがわかります。

私は機能レベルがWindows Server 2008の新しいドメインを持っています。これは認証が機能しないドメインです。チケットを検証しようとするとアプリケーションエラーが返されます。

Kerberos validation not successful... 

Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed) 
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) 
    at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(Unknown Source) 
    at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) 
    at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) 
    at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:146) 
    at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:136) 
    ... 34 more 
Caused by: KrbException: Checksum failed 
    at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source) 
    at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source) 
    at sun.security.krb5.EncryptedData.decrypt(Unknown Source) 
    at sun.security.krb5.KrbApReq.authenticate(Unknown Source) 
    at sun.security.krb5.KrbApReq.<init>(Unknown Source) 
    at sun.security.jgss.krb5.InitSecContextToken.<init>(Unknown Source) 
    ... 43 more 
Caused by: java.security.GeneralSecurityException: Checksum failed 
    at sun.security.krb5.internal.crypto.dk.ArcFourCrypto.decrypt(Unknown Source) 
    at sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(Unknown Source) 

スタックトレースが「ArcfourCrypto.decryptは」そう、おそらくRC4-HMACとしてKerberosチケットを扱っている示しています。今度はkerbtrayを使ってチケットを調べると、クライアントの2つのチケットkrbtgt/.COMがあります。両方のチケットには、RSA暗号化タイプRSADS1 RC4-HMACがあり、チケット暗号化タイプにはこれもありますが、もう一方には「Kerberos AES256-CTS-HMAC-SHA1-96」があります。

これが問題の原因であるかどうかはわかりませんが、認証例外について説明する2つの環境で唯一の違いが見つかりました。私はAD暗号化ポリシーを変更しようとしましたが、IEとFirefoxを試してみました。

これに対処するお手伝いがあれば幸いです。私はおそらく、プロダクションのAD設定についてあまり指示することができないので、私はそれをJavaエンドで修正することを好むでしょう。

+0

Wiresharkでの通信を確認して、チケットを調べましたか? –

+0

ありがとう@マイケル - O - 私はこれ以前の作業でWiresharkを使用しましたが、出力を使用できなくなってしまいました。これはまったく動作しませんでした。テストドメインをWindows Server 2003の機能レベルに戻しましたそしてそれは正常に働いた。今私は、新しい2008年のテストドメインを設定して、実行可能なソリューションを見つけようとする必要があります。 – slt

答えて

0

問題は、トークンが生成される方法と、サーバー側でどのように検証されるかにあります。例外トレースから、問題があること、クライアント側がチェックサムを設定していないこと、およびサーバー側がチェックサムを検証することを示しています。チェックサムは、明白な意味を持つトークンに設定されたparams値の1つです。

チェックサムチェックを無視するには、この機能を無効にする方法が2008年に存在する必要があります。しかし、別のドアが開き、残存リスクを評価する必要があるかもしれません。

16

問題はキータブにあるようです。 (A)keytabはJavaでは動作しますが、k5start/kinitでは動作しません。 (B)keytabはJavaでは動作しませんが、k5start/kinitで動作します。 (C)keytabは、両方で動作します。

Javaはkeytabファイル使用して認証できるかどうかを確認することができます短いJavaコード:使用する

import java.io.File; 
import java.io.FileInputStream; 
import java.io.InputStream; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Properties; 

import javax.security.auth.Subject; 

import com.sun.security.auth.module.Krb5LoginModule; 

/** 
* This is simple Java program that tests ability to authenticate 
* with Kerberos using the JDK implementation. 
* 
* The program uses no libraries but JDK itself. 
*/ 
public class Krb { 

    private void loginImpl(final String propertiesFileName) throws Exception { 
    System.out.println("NB: system property to specify the krb5 config: [java.security.krb5.conf]"); 
    //System.setProperty("java.security.krb5.conf", "/etc/krb5.conf"); 

    System.out.println(System.getProperty("java.version")); 

    System.setProperty("sun.security.krb5.debug", "true"); 

    final Subject subject = new Subject(); 

    final Krb5LoginModule krb5LoginModule = new Krb5LoginModule(); 
    final Map<String,String> optionMap = new HashMap<String,String>(); 

    if (propertiesFileName == null) { 
     //optionMap.put("ticketCache", "/tmp/krb5cc_1000"); 
     optionMap.put("keyTab", "/etc/krb5.keytab"); 
     optionMap.put("principal", "foo"); // default realm 

     optionMap.put("doNotPrompt", "true"); 
     optionMap.put("refreshKrb5Config", "true"); 
     optionMap.put("useTicketCache", "true"); 
     optionMap.put("renewTGT", "true"); 
     optionMap.put("useKeyTab", "true"); 
     optionMap.put("storeKey", "true"); 
     optionMap.put("isInitiator", "true"); 
    } else { 
     File f = new File(propertiesFileName); 
     System.out.println("======= loading property file ["+f.getAbsolutePath()+"]"); 
     Properties p = new Properties(); 
     InputStream is = new FileInputStream(f); 
     try { 
     p.load(is); 
     } finally { 
     is.close(); 
     } 
     optionMap.putAll((Map)p); 
    } 
    optionMap.put("debug", "true"); // switch on debug of the Java implementation 

    krb5LoginModule.initialize(subject, null, new HashMap<String,String>(), optionMap); 

    boolean loginOk = krb5LoginModule.login(); 
    System.out.println("======= login: " + loginOk); 

    boolean commitOk = krb5LoginModule.commit(); 
    System.out.println("======= commit: " + commitOk); 

    System.out.println("======= Subject: " + subject); 
    } 

    public static void main(String[] args) throws Exception { 
    System.out.println("A property file with the login context can be specified as the 1st and the only paramater."); 
    final Krb krb = new Krb(); 
    krb.loginImpl(args.length == 0 ? null : args[0]); 
    } 
} 

、およびプロパティファイルを:

#ticketCache=/tmp/krb5cc_1000 
keyTab=/etc/krb5.keytab 
principal=foo 

doNotPrompt=true 
refreshKrb5Config=true 
useTicketCache=true 
renewTGT=true 
useKeyTab=true 
storeKey=true 
isInitiator=true 

我々はそのKRBを想定(下/ kdcファイルが削除され、トークンキャッシュが削除され、ユーザー "foo"がデータベースから削除されます)

kdb5_utilを使用してデータベースが作成されます。

次のアクションシーケンスがキータブ状態(A)につながる:

$ echo -e "foo\nfoo" | kadmin.local -q "addprinc foo" 
$ echo -e "foo\nfoo" | kadmin.local -q "ktadd foo" 
$ java -cp . Krb ./krb5.properties 
# Now java auth okay, but the following command fails: 
$ k5start foo 
Kerberos initialization for [email protected] 
Password for [email protected]: 
k5start: error getting credentials: Decrypt integrity check failed 
$ 

次のアクションシーケンスがキータブ状態(B)につながる:

$ echo -e "foo\nfoo" | kadmin.local -q "addprinc foo" 
$ echo -e "foo\nfoo" | kadmin.local -q "ktadd foo" 
$ echo -e "foo\nfoo" | kadmin.local -q "cpw foo" 
$ java -cp . Krb ./krb5.properties 
A property file with the login context can be specified as the 1st and the only paramater. 
NB: system property to specify the krb5 config: [java.security.krb5.conf] 
1.6.0_33 
======= loading property file [/tmp/krb-test/yhadoop-common/./krb5.properties] 
Debug is true storeKey true useTicketCache true useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is /etc/krb5.keytab refreshKrb5Config is true principal is foo tryFirstPass is false useFirstPass is false storePass is false clearPass is false 
Refreshing Kerberos configuration 
Config name: /etc/krb5.conf 
>>> KdcAccessibility: reset 
>>> KdcAccessibility: reset 
Acquire TGT from Cache 
>>>KinitOptions cache name is /tmp/krb5cc_0 
Principal is [email protected] 
null credentials from Ticket Cache 
>>> KeyTabInputStream, readName(): EXAMPLE.COM 
>>> KeyTabInputStream, readName(): foo 
>>> KeyTab: load() entry length: 49; type: 23 
Added key: 23version: 3 
Ordering keys wrt default_tkt_enctypes list 
default etypes for default_tkt_enctypes: 23. 
0: EncryptionKey: keyType=23 kvno=3 keyValue (hex dump)= 
0000: 5F 7F 9B 42 BB 02 51 81 32 05 1D 7B C0 9F 19 C0 _..B..Q.2....... 


principal's key obtained from the keytab 
Acquire TGT using AS Exchange 
default etypes for default_tkt_enctypes: 23. 
>>> KrbAsReq calling createMessage 
>>> KrbAsReq in createMessage 
>>> KrbKdcReq send: kdc=localhost UDP:88, timeout=30000, number of retries =3, #bytes=128 
>>> KDCCommunication: kdc=localhost UDP:88, timeout=30000,Attempt =1, #bytes=128 
>>> KrbKdcReq send: #bytes read=611 
>>> KrbKdcReq send: #bytes read=611 
>>> KdcAccessibility: remove localhost:88 
>>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType 
Checksum failed ! 
       [Krb5LoginModule] authentication failed 
Checksum failed 
Exception in thread "main" javax.security.auth.login.LoginException: Checksum failed 
     at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:696) 
     at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542) 
     at Krb.loginImpl(Krb.java:65) 
     at Krb.main(Krb.java:77) 
Caused by: KrbException: Checksum failed 
     at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(ArcFourHmacEType.java:85) 
     at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(ArcFourHmacEType.java:77) 
     at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:168) 
     at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:87) 
     at sun.security.krb5.KrbAsReq.getReply(KrbAsReq.java:446) 
     at sun.security.krb5.Credentials.sendASRequest(Credentials.java:401) 
     at sun.security.krb5.Credentials.acquireTGT(Credentials.java:350) 
     at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:672) 
     ... 3 more 
Caused by: java.security.GeneralSecurityException: Checksum failed 
     at sun.security.krb5.internal.crypto.dk.ArcFourCrypto.decrypt(ArcFourCrypto.java:388) 
     at sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(ArcFourHmac.java:74) 
     at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(ArcFourHmacEType.java:83) 
     ... 10 more 
$ 

しかし"k5start foo"はこの状態でOKであり、 "kinit foo"と同様です。


そして、次のアクションシーケンスは、状態(C)につながる:その両方k5start/kinitを使用した後

$ echo -e "foo\nfoo" | kadmin.local -q "addprinc foo" 
$ ktutil 
ktutil: addent -password -p foo -k 1 -e rc4-hmac 
Password for [email protected]: 
ktutil: wkt /etc/krb5.keytab 
ktutil: q 

とJavaの検証が肯定的な結果を与えます。


環境:

yum list krb5-appl-servers krb5-libs krb5-server krb5-workstation kstart pam_krb5 
... 
Installed Packages 
krb5-libs.x86_64                   1.9-33.el6_3.3                  @updates 
krb5-server.x86_64                   1.9-33.el6_3.3                  @updates 
krb5-workstation.x86_64                  1.9-33.el6_3.3                  @updates 
kstart.x86_64                    4.1-2.el6                   @epel 
... 
$ cat /etc/redhat-release 
CentOS release 6.3 (Final) 
$ java -version 
java version "1.6.0_33" 
Java(TM) SE Runtime Environment (build 1.6.0_33-b03) 
Java HotSpot(TM) 64-Bit Server VM (build 20.8-b03, mixed mode) 

また、Java 7 で観察し、同じ動作も同じ動作は、MITのKerberosで正確なUbuntuの(12.04.1 LTS)で観察された5-1.10.3コンパイルソースディストリビューションから。

+4

ニースの完全な答え! – Hbcdev

+0

@Ivan - キータブからチケットを取得できました。しかし、Java 7のコードでは、これはChecksumのエラーで突然失敗しました。キータブを唯一のオプションとして作り直していますか? –

関連する問題