jTDS を使用して SQLServer に接続しています。内部的に、jTDS は GSS を使用して kerberos のサービス チケットを取得し、安全なコンテキストを確立します。私のアプリは長期間存続し、接続は常に維持されているため、SQL サーバーが独自にそれらを更新できるようにするには、kerberos のサービス チケットを更新可能にする必要があります (kdc ポリシーは、12 時間後にすべてのチケットを期限切れにするように設定されています)。 )。
jTDS が kerberos トークンを取得するために行うことは、(多かれ少なかれ) 次のとおりです。
GSSManager manager = GSSManager.getInstance();
// Oids for Kerberos5
Oid mech = new Oid("1.2.840.113554.1.2.2");
Oid nameType = new Oid("1.2.840.113554.1.2.2.1");
// Canonicalize hostname to create SPN like MIT Kerberos does
GSSName serverName = manager.createName("MSSQLSvc/" + host + ":" + port, nameType);
GSSContext gssContext = manager.createContext(serverName, mech, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestMutualAuth(false);
gssContext.requestCredDeleg(true);
byte[] ticket = gssContext.initSecContext(new byte[0], 0, 0);
私が疑っているのは、私が取得しているチケットは更新できないということです。次のようなことをして確認しています。
ExtendedGSSContext extendedContext = (ExtendedGSSContext) gssContext;
boolean[] flags = (boolean[]) extendedContext.inquireSecContext(InquireType.KRB5_GET_TKT_FLAGS);
System.out.println("Renewable = " + flags[8]);
特定の構成では、GSS は JAAS ログイン モジュールから kerberos TGT を取得しています。次の変数を false-Djavax.security.auth.useSubjectCredsOnly=false
に設定し、login.cfg ファイルで次のログイン モジュールを構成します。
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useKeytTab=true
keyTab="/home/batman/.batman.ktab"
principal="batman@GOTHAMCITY.INT"
storeKey=true
doNotPrompt=true
debug=false
};
もう 1 つ気づいたことは、 のgetLifetime()
方法がGSSContext
機能していないように見えることです。チケットの実際の有効期間に関係なく、常に 2147483647 (最大 int) を返します。
jTDS ドライバーの分岐に慣れているので、必要に応じて GSS コンテキストを確立する方法を変更できます。
私が試したこと:
GSS API のネイティブ実装を使用します。
これは、更新可能なチケットを取得するという点ではうまく機能しますが、別の問題が発生します (チケットキャッシュが適切に設定され、そこにあるチケットが適切に更新されることを保証するという点で)。このオプションをバイパスできれば、それはいいことです。ここで私が観察したことは、getLifetime()
メソッドが実際にチケットの実際の有効期間を秒単位で返すことです。
KerberosLoginModule の再実装:
この質問Jaas - Requesting Renewable Kerberos Ticketsへの回答に基づいて、LoginModule を再実装して、TGT を要求する前にKDCOption
RENEWを設定しました。KrbAsReqBuilder
これは、更新可能な TGT を取得するという意味では問題なく機能しますが、GSS がその TGT から取得したチケットはまだ更新できません。KDCOption オブジェクトのコンストラクターにブレークポイントを設定し、要求ごとに手動で RENEW フラグを設定すると ( KrbTgsReq
GSS によって行われた場合でも) 動作しますが、その変更を生産的にするには、GSS を大幅に書き直す必要があり、快適ではありません。