2015-12-16 5 views
5

と私は、この目的のために、私はKerberosチケットを検証することを選択した、Windowsドメインログインに基づいてSSOを使用したWeb appliactionを働いています。しかし、今私は解決策を見つけることができない問題に直面しています。私は、例外なしでチケットを検証するために管理し、私はユーザー名を取得しようとしている時にユーザ名がnullあるので、NullPointerExceptionは、スローされ、問題がどこにあるか私にはわかりません。私は検証中に例外を取得しない場合GSSContextのはヌルSRCNAME

はなぜヌルのユーザー名ですか?私はこれに基づいて、私のクライアントを作成 String clientName = gssContext.getSrcName().toString();

:どのように私は、ユーザー名を取得

Using GSSManager to validate a Kerberos ticket

How to obtain a kerberos service ticket via GSS-API?

http://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/single-signon.html

更新私も同じだ

このhttps://spring.io/blog/2009/09/28/spring-security-kerberos-spnego-extensionに基づいてIセットアップ春のセキュリティの場合:

final Oid spnegoOid = new Oid("1.3.6.1.5.5.2"); 

GSSManager gssmgr = GSSManager.getInstance(); 

// tell the GSSManager the Kerberos name of the service 
GSSName serviceName = gssmgr.createName(this.servicePrincipal, GSSName.NT_USER_NAME); 

// get the service's credentials. note that this run() method was called by Subject.doAs(), 
// so the service's credentials (Service Principal Name and password) are already 
// available in the Subject 
GSSCredential serviceCredentials = gssmgr.createCredential(serviceName, 
     GSSCredential.INDEFINITE_LIFETIME, spnegoOid, GSSCredential.ACCEPT_ONLY); 

// create a security context for decrypting the service ticket 
GSSContext gssContext = gssmgr.createContext(serviceCredentials); 

// decrypt the service ticket 
System.out.println("Entering accpetSecContext..."); 
System.out.println(new String (Base64.encodeBase64(gssContext.acceptSecContext(this.kerberosTicket, 0, 
     this.kerberosTicket.length)))); 

// get the client name from the decrypted service ticket 
// note that Active Directory created the service ticket, so we can trust it 
String clientName = gssContext.getSrcName().toString(); 

アップデート2:1:どのようにセットアップの内容は、ここだけのコピー&ペーストを形成https://stackoverflow.com/a/25450862/1646082

エラー:

java.lang.NullPointerException at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:136) at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:125) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422)

private static class KerberosValidateAction implements PrivilegedExceptionAction<String> { 
    byte[] kerberosTicket; 

    public KerberosValidateAction(byte[] kerberosTicket) { 
     this.kerberosTicket = kerberosTicket; 
    } 

    @Override 
    public String run() throws Exception { 
     GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null); 
     context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length); 
     String user = context.getSrcName().toString(); // ERROR! 
     context.dispose(); 
     return user; 
    } 

} 

アップデート3:ここDomain authentication with Kerberos fails提案されているよう

も1.7から1.8からの変更Javaバージョンを試してみました。検索結果はありません。

更新4:すべての

まず。 Java 1.8 b40とb45を使用しないでください。両方とも壊れています。そして、ローカルPCでテストしないでください、それは動作しません(私はなぜわかりません)。

最新(B65)は、Javaのバージョンを上変更した後、私はencription(AP REPを復号化するための適切なタイプのキーを見つけることができません - AES256 ...)についての例外が発生しました。この私が、私は例外を得たすべてのこの後のJava 1.8のJava暗号化拡張機能(JCE)によって固定され、/crypto AES256-SHA1と再作成キータブています

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 GssServer$GssServerAction.run(GssServer.java:159) ... 4 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.(Unknown Source) at sun.security.jgss.krb5.InitSecContextToken.(Unknown Source) ... 8 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) ... 14 more

「私はthis tutorialとkeytabfileを作成するための他の方法を試してみましたが、私はまだドン解決策があります。

+0

してください、私はこれは古いスレッドです知っているが、私は最近、正確に同じ問題を持っていたし、私の場合、それはSPNとの問題だったあなたは、コンテキスト –

+1

を確立するために使用するコードを示しています。 私は自分のサービスを呼び出し、cmdで 'klist'と入力して私のサービスを探しました。私はそれを見つけた後、私はこのような何かを見た:HTTP/[email protected]。このためのSPNが作成されていることを確認する必要があります。サービスアカウントを作成し、 'setspn -a HTTP/service.domain.com domain \ serviceAccout'でspnを作成した後、' ktab -k FILE:your_filename.ktab -a HTTP/service.domain.comドメインを持つキータブを作成します。 \ password_of_service_account'となります。 – Nico

答えて

1

あなたがSRCNAMEを取得しようとしているとき、コンテキストが完全に確立されていないようです。これは、ScrNameがnullになる理由のようです。 https://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.security.api.doc/jgss/org/ietf/jgss/GSSContext.htmlによると、acceptSecContext()はトークンを生成し、それがヌルでない場合、このトークンをピアに送信する必要があります。 acceptSecContext()の呼び出し後、isEstablished()がfalseを返すかどうかを確認する必要があります。それはそうなら、

If this method returns false it indicates that a token is needed from its peer in order to continue the context establishment phase. A return value of true signals that the local end of the context is established. This may still require that a token be sent to the peer, if one is produced by GSS-API. During the context establishment phase, the isProtReady() method may be called to determine if the context can be used for the per-message operations. This allows applications to use per-message operations on contexts which aren't fully established.

同じチュートリアルhttp://www.cs.mun.ca/java-api-1.5/guide/security/jgss/tutorials/BasicClientServer.htmlでより詳細に説明されています

The acceptSecContext method may in turn return a token. If it does, the acceptor should send that token to the initiator, which should then call initSecContext again and pass it this token. Each time initSecContext or acceptSecContext returns a token, the application that called the method should send the token to its peer and that peer should pass the token to its appropriate method (acceptSecContext or initSecContext). This continues until the context is fully established (which is the case when the context's isEstablished method returns true).

+1

残念ながら、それは役に立ちません。 – Vartlok

1

オラクルGSSAPIの変形例である私のGSSAPIソケットのデモを実施したときに、私は同じChecksum failedエラーに直面しましたtutorialコード。 FreeIPA Kerberos領域に登録されたLinuxマシンで自分のコードを実行しました。 私のLinuxシステムのバニラkrb5.confファイルを使用しました。チケットetype上の制約はない。

... 
[libdefaults] 
    default_realm = AUTHDEMO.IT 
    dns_lookup_realm = true 
    dns_lookup_kdc = true 
    rdns = false 
    ticket_lifetime = 24h 
    forwardable = true 
    udp_preference_limit = 0 
... 

FreeIPAのレルムのデフォルトは18型チケット(AES-256)を使用することです。

私のアプリケーションについて

、それは、このポリシーファイル構成されています。エラーがで発生する私の場合は

GSSException: Failure unspecified at GSS-API level (Mechanism level: Encryption type AES256CTS mode with HMAC SHA1-96 is not supported/enabled)

:私はアクセプター側でこのエラーを得たアプリケーションを実行すると

grant CodeBase "file:./app.jar" { 
     permission java.security.AllPermission; 
}; 

grant CodeBase "file:./app.jar" 
    Principal javax.security.auth.kerberos.KerberosPrincipal 
     "[email protected]" { 

    permission java.net.SocketPermission "*", "accept"; 

    permission javax.security.auth.kerberos.ServicePermission 
     "[email protected]", "accept"; 
}; 

をGSSアクセプター側。私のアプリケーションでは、プログラムでJaasの設定を生成します(これについては、DConfigとして参照します)、設定ファイルは使用しません。 私が見つけた最初の解決策は、DConfigの代わりに設定ファイルを使用することです。問題は消えて、うまくいきました。 一時的な解決策、JAAS設定ファイル:この構成で

DemoServer { 
    com.sun.security.auth.module.Krb5LoginModule required 
    principal="[email protected]" 
    storeKey=true 
    debug=true; #not mandatory 
}; 

は、何の問題は、アクセプター側で発生していないとアプリケーションは、サービスチケットの有効性を確認し、接続を受け入れることができました。

私は自分自身に質問しました.. なぜですか?

2つの設定で取得した科目の相違点を確認しました。設定ファイルでは、サブジェクトはプライベート資格情報にパスワードハッシュの資格情報とプリンシパルTGTチケットの両方を含んでいます。 DConfigでは、パスワードハッシュのみでSubjectを取得できますが、プライベートクレデンシャルにはプリンシパルTGTチケットはありません。

マイ修正

含むdConfigは、設定ファイルの同じ設定が含まれており、最初に私は不正行為の理由を見ることができないで、他のオプションは、Krb5LoginModuleデフォルトのレプリカです。

アクセプタ側DConfigにisInitiator = trueを設定すると、この問題が解決されました。 `isInitiator = trueは、TGTチケットの永続性を強制されました。

この回避策では、システムkrb5.confに変更を加えずにエラーが消えました。

私はJaasのログイン後、クレジットが不足しているというあなたのサブジェクトの秘密の資格情報をチェックしてみましょう。アクセプタ側にもisInitiator = trueを設定しようとすると、サービスのプリンシパルTGTが必要です。

よろしく