1

我寫客戶端代碼爲Windows Kerberos身份驗證與服務(日誌代碼省略):電話GSSContext.initSecContext失敗間歇性:收到超時

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,大約一分鐘後拋出異常:

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

當我啓用Kerberos調試輸出(通過取消註釋上面的第二線),我可以看到該協議有時卡在行:

getKDCFromDNS using UDP 

A Java Kerberos troubleshooting website表明,這是與Kerberos身份驗證服務器的問題,但我知道,服務器啓動並運行,因爲我們有在C#編寫類似的代碼(使用。 NET庫),永遠不會卡住。

回答

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:在HKLM\System\CurrentControlSet\Control\Lsa\Kerberos,設置DWORDMaxPacketSize1
  • 2003/Vista/7的:在HKLM\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters,設置DWORDMaxPacketSize1

(需要注意的是相同的註冊表目錄也需要DWORDAllowTGTSessionKey設置爲1,Kerberos才能在所有的工作。)

+2

如果您,您的管理員必須修復DNS。 – 2013-03-19 18:23:22