1

サービスを使用した Windows Kerberos 認証のクライアント側コードを作成しています (ログ コードは省略されています)。

System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
// System.setProperty("sun.security.krb5.debug", "true");
Package thisPkg = AuthHelper.class.getPackage();
String configPath = Util.getConfigPath(thisPkg, "jaas.conf");
System.setProperty("java.security.auth.login.config", "=" + configPath);
GSSManager manager = GSSManager.getInstance();
GSSName peerName = manager.createName(spn, GSSName.NT_HOSTBASED_SERVICE);
GSSContext context = manager.createContext(peerName, null, null,
    GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(true); // required
context.requestCredDeleg(true); // required for publish
byte[] serverTokenBytes = new byte[0];
while (!context.isEstablished()) {
  byte[] clientTokenBytes = context.initSecContext(serverTokenBytes, 0,
      serverTokenBytes.length);
  if (clientTokenBytes != null)
    socket.send(createClientMessage(clientTokenBytes));
  if (context.isEstablished()) break;
  Message message = socket.receive();
  String serverToken = message.getFirst("SERVERTOKEN").toString();
  serverTokenBytes = Base64.decodeBase64(serverToken);
}

jaas.conf単に含まれている場所:

sp {
  com.sun.security.auth.module.Krb5LoginModule required debug=true;
};

allowtgtsessionkeyまた、必要に応じてレジストリ キーを設定し、JCE Unlimited Strength Jurisdiction Policy Files 7をインストールしました。

コードが機能する場合があります (つまり、相互認証が確立されます)。ただし、 への最初の呼び出しでしばらくスタックし、GSSContext.initSecContext約 1 分後に例外がスローされることがあります。

Exception in thread "main" GSSException: No valid credentials provided (Mechanism level: Receive timed out)
  ...
Caused by: java.net.SocketTimeoutException: Receive timed out
  ...

Kerberos デバッグ出力を有効にすると (上記の 2 行目のコメントを解除して)、プロトコルが次の行でスタックすることがあります。

getKDCFromDNS using UDP

Java Kerberos のトラブルシューティング Web サイトでは、これは Kerberos 認証サーバーの問題であることが示唆されていますが、サーバーが稼働していることはわかっています。C# で (.NET ライブラリを使用して) 書かれた同様のコードがスタックすることはないからです。

4

1 に答える 1

1

Kerberos 認証サーバーの DNS 解決が間接的に行われているように見えますが、これは信頼できません。サーバーを明示的に (コードの最初のどこかで) 指定すると、そのリダイレクトはバイパスされます。

System.setProperty("java.security.krb5.realm", "<YOUR_KRB_REALM>");
System.setProperty("java.security.krb5.kdc", "<YOUR_KRB_SERVER_ADDR_OR_IP>");

編集: Kerberos サーバーとの通信は、UDP を使用するプロトコルのために本質的に信頼性が低いことが判明したため、比較的遠くにあるサーバーでは失敗する可能性が高くなりました。Windows 8 はデフォルトで TCP を使用します。以前のバージョンでTCPを強制するには:

  • XP/2000 :で、 DWORDHKLM\System\CurrentControlSet\Control\Lsa\Kerberosに設定します。 MaxPacketSize1
  • 2003/Vista/7 :で、 DWORDHKLM\System\CurrentControlSet\Control\Lsa\Kerberos\Parametersに設定します。 MaxPacketSize1

( Kerberos が機能するには、同じレジストリ ディレクトリでもDWORD AllowTGTSessionKeyを に設定する必要があることに注意してください。)1

于 2013-03-19T14:02:43.233 に答える