2016-03-29 16 views
3

私は、Windows上で実行されている単純なJava HTTPクライアントを作成しました。クライアントは、SPNegoを介したKerberos認証が必要なWebサーバーと通信します。Windows Javaクライアントを使用してKerberosサービスチケットを保存する方法は?

  • サービスチケットが私の信任状キャッシュに格納されていない:

    は、私は2つの問題が発生しています。要求を実行した後、資格キャッシュにケルベロスサービスチケットがC:\Users\<user>\krb5cc_<user>の下に格納されていることが予想されました.Javaがサービスチケットを資格キャッシュに格納すると仮定するのは間違っていましたか?私は、クライアントBでの要求に対してクライアントAで取得したサービスチケットを再利用したい(両方のクライアントが同じマシン上のJavaアプリケーションである)。これはJavaで可能ですか?

  • ループで100回以下のコードを実行すると、n回だけ動作します(nは1〜100の乱数です)。 Javaがサービスチケットを取得することができなかったため、失敗したリクエストは401エラーメッセージを返します(アプリケーション間でサービスチケットをリクエスト間に保存しないため、リクエストごとにTGTから新しいサービスチケットを取得しようとします) 。この質問の最後にエラーメッセージを追加しました。

JDKのbinフォルダにkinit経由でTGTを作成しました。次のコードスニペットは、単純なGETリクエストを作成するために使用されます。

static void testJavaHttpKerberosAuthentication() throws IOException { 
    URL obj = new URL(URI); 
    HttpURLConnection con = (HttpURLConnection) obj.openConnection(); 
    int responseCode = con.getResponseCode(); 
    System.out.println("\nSending 'GET' request to URL : " + URI); 
    System.out.println("Response Code : " + responseCode); 

    BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream())); 
    String inputLine; 
    StringBuffer response = new StringBuffer(); 
    while ((inputLine = in.readLine()) != null) { 
     response.append(inputLine); 
    } 
    in.close(); 

    //print result 
    System.out.println(response.toString()); 
    } 

hereを説明するように)ここに私のjaas.confをの内容です:

com.sun.security.jgss.krb5.initiate { 
com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false useTicketCache=true; 
}; 

私は次のパラメータを使用して自分のアプリケーションを実行していますよ:

-Djava.security.auth.login.config=D:\jaas.conf 
-Dsun.security.krb5.debug=true 
-Djavax.security.auth.useSubjectCredsOnly=false 

クライアントがドメイン構成から正しいKDCを取得するため、私はkrb5.iniとして使用しません。私の資格情報は、次のコマンドを使用してキャッシュの

私はTGTを生成できます(参考文献課題2)

C:\Program Files\Java\jdk1.8.0_77\bin>kinit 
Password for <user>@<domain>: 
New ticket is stored in cache file C:\Users\<user>\krb5cc_<user> 

をそして最後に、ここでの認証に失敗した場合の例外とKerberosデバッグ出力です。 ctimeは間違っていることに注意してください。私は、1970年から2040年にかけて、さまざまな試みとタイムレンジを持っています。興味深いことに、これはすべての要求に対して起こるわけではありません。

>>>KRBError: 
cTime is Wed Jun 07 12:24:03 CEST 2017 1496831043000 
sTime is Tue Mar 29 16:38:24 CEST 2016 1459262304000 
suSec is 283371 
error code is 34 
error Message is Request is a replay 
sname is HTTP/<spn>@<domain> 
msgType is 30 
KrbException: Request is a replay (34) - PROCESS_TGS 

は、私はすでにJAASは Subject.doAsを使用して動作するようにしようとしたが、これは同じ問題を引き起こしています。ブラウザーを介してサーバーにアクセスすることはうまくいきます(ただし、ブラウザーはWindows固有の信任状キャッシュAFAICTを使用しています)。

このような問題をデバッグする方法についていくつかアドバイスをいただき、ありがとうございます。

EDIT:環境変数KRB5CCNAMEを介して資格情報キャッシュへのパスを明示的に指定しても、動作は変更されません。 TGTは資格キャッシュから取得されたものの、サービスチケットはそこに保存されていないようです。

+0

ところで、2つの余分なトレースフラグがあります: '-Djava.security.debug = gssloginconfig、configfile、configparser、JAAS設定のデバッグ用のlogincontext'、もちろん' -Dsun.security.spnego.debug = true' –

答えて

0

キャッシュについて>>システムのデフォルトキャッシュとは何も指定していないようです(cf.env変数KRB5CCNAME)、Javaとkinitはハードコードされたデフォルトに戻ります。そしてそれは、同じデフォルトではありません...

    kinitのバージョンがはっきりつまり、Linuxの標準を使用しています
  • FILE:
  • Javaは通常、MIT-のKerberos-ため、Windowsのサービスによって管理API:つまり、Windowsの標準を使用しています

考えられる回避策:WindowsでKerberos UIを使用してTGTを作成するか、Javaでファイルキャッシュを使用するように設定する(KRB5CCNAME)。

参考:MIT Kerberos documentation、特にハードコーディングされたデフォルトについては非常に最後のリンクのランダムな時間の値について

~~~~~~~

>>私は見当もつかない。

+0

あなたのお返事ありがとうございます、サムソン。私は、Javaが資格証明キャッシュにデフォルトでLinux標準を使用しているという印象を受けました([The Initial Credentials](http://cr.openjdk.java.net/~weijun/special/krb5winguide-2/raw_files/)。新しい/ kwin))。少なくとも、Javaはユーザーフォルダ内の資格情報キャッシュでTGTを見つけることができました。それにもかかわらず、私はKRB5CCNAMEによって資格証明キャッシュを明示的に指定しようとしましたが、動作を変更しませんでした。私のHTTP要求はサービスチケットを取得していますが、資格情報キャッシュには格納されていません。 – Thomas

+0

Hmm ... TGTの管理をデフォルトのJAASルーチンに委譲している間に、HTTPライブラリがサービスチケット(たとえば、クライアント{...})を管理するために別のJAAS設定エントリを使用する可能性がありますconfigエントリ(つまり、 'com.sun.security.jgss.krb5.initiate {...}')?!? –

+0

私はjava.netコンポーネントのみを使用しており、[このドキュメント](http://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/lab/part6.html)を検討しています。 'jaas.conf 'の他のエントリは、手元の例と関連があると考えています。 Javaで資格キャッシュにサービスチケットを保存するプロセスを記述しているソースが見つかりません。何らかの理由で私のために動作しないデフォルトの動作か、不可能であるかのように見えます。 – Thomas

0

時々発生するランダムな時間値について:をkrb5.iniに設定すると、問題が解決されることがわかりました。これは事実上、Kerberosに常にパッケージを送信するためにTCPを最初に使用するように指示します。明らかに、UDPに切り替えるときに問題があります(UDPが問題であるかプロトコル間で切り替えるかは不明です)。

+0

UDPは多くの、そして一見無関係な問題に関係しているようです。https://steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/errors.html –

0

JAASはチケットをキャッシュに保存しないため、kinitを使用するか、プログラムによってkinitコードをコードで呼び出す必要があります。 私はこの問題に関する質問/回答をhereと書いています。

関連する問題