Java 当 kerberos 票证到期时客户端挂起
Java client hangs when kerberos ticket expires
我们已经实施了 Kerberos java 客户端并且运行良好。然而,当 kerberos 票证过期时 Java 客户端应用程序在控制台中请求用户名,这反过来使应用程序挂起。在像 SoapUI 这样的工具中,我们观察到系统在 Kerberos 票证过期时抛出 Unauthorized 错误。我们想要实现类似的行为,即如果 Kerberos 票证到期应抛出未经授权的错误,而不是等待用户输入凭据。请帮忙
正在为 Kerberos 测试设置客户端系统
第 1 步:将密钥添加到 windows 注册表:
物品价值
键 hkey_local_machine\system\currentcontrolset\control\lsa\kerberos
值名称 allowtgtsessionkey
值类型 reg_dword
值 0x01
第 2 步:在 ClientKerberosAuthentication.java 主 class 中添加一个 java 系统 属性:
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
第 3 步:获取票证授予票证 (tgt):
运行 用于获取票证授予票证的 kinit 实用程序。您可以在 /jre/bin 目录中找到此实用程序。
例如:C:\Program Files\Java\jdk1.7.0_79\bin\kinit spnuser7
密码:test@123
ClientKerberosAuthentication.java
public class ClientKerberosAuthentication {
public static Credentials getCredentials() {
return new NTCredentials("", "", "desktop.test.com", "test.com");
}
public static void main(String[] args) throws Exception {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, new SPNegoSchemeFactory());
Credentials use_jaas_creds = getCredentials();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(null, -1, null),
use_jaas_creds);
HttpUriRequest request = new HttpGet("http://kerbserver7.com/kerbservice/Service1.svc?wsdl");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println("----------------------------------------");
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
}
System.out.println("----------------------------------------");
EntityUtils.consume(entity);
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}
我认为问题是缺少 jaas 配置文件。应该有 java.security.auth.login.config
的设置。在没有定义的 jaas.conf 文件的情况下, doNotPompt
设置为 false(表示它会提示)。这与 OP 对提示的观察中描述的行为相匹配。
解决方案是创建一个 jaas 配置文件并使用上述 属性 指定该文件。在所述 jaas.conf 文件中,设置 doNotPrompt=true
.
示例:
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true
useTicketCache=true
renewTGT=true
doNotPrompt=true
useKeyTab=false
storeKey=true
debug=true
;
};
主要讨论在 Krb5LoginModule
的 JavaDocs 中
这里有一些额外的信息:http://cr.openjdk.java.net/~weijun/special/krb5winguide-2/raw_files/new/kwin
我们已经实施了 Kerberos java 客户端并且运行良好。然而,当 kerberos 票证过期时 Java 客户端应用程序在控制台中请求用户名,这反过来使应用程序挂起。在像 SoapUI 这样的工具中,我们观察到系统在 Kerberos 票证过期时抛出 Unauthorized 错误。我们想要实现类似的行为,即如果 Kerberos 票证到期应抛出未经授权的错误,而不是等待用户输入凭据。请帮忙
正在为 Kerberos 测试设置客户端系统 第 1 步:将密钥添加到 windows 注册表: 物品价值 键 hkey_local_machine\system\currentcontrolset\control\lsa\kerberos 值名称 allowtgtsessionkey 值类型 reg_dword 值 0x01
第 2 步:在 ClientKerberosAuthentication.java 主 class 中添加一个 java 系统 属性: System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
第 3 步:获取票证授予票证 (tgt): 运行 用于获取票证授予票证的 kinit 实用程序。您可以在 /jre/bin 目录中找到此实用程序。 例如:C:\Program Files\Java\jdk1.7.0_79\bin\kinit spnuser7 密码:test@123
ClientKerberosAuthentication.java
public class ClientKerberosAuthentication {
public static Credentials getCredentials() {
return new NTCredentials("", "", "desktop.test.com", "test.com");
}
public static void main(String[] args) throws Exception {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, new SPNegoSchemeFactory());
Credentials use_jaas_creds = getCredentials();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(null, -1, null),
use_jaas_creds);
HttpUriRequest request = new HttpGet("http://kerbserver7.com/kerbservice/Service1.svc?wsdl");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println("----------------------------------------");
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
}
System.out.println("----------------------------------------");
EntityUtils.consume(entity);
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}
我认为问题是缺少 jaas 配置文件。应该有 java.security.auth.login.config
的设置。在没有定义的 jaas.conf 文件的情况下, doNotPompt
设置为 false(表示它会提示)。这与 OP 对提示的观察中描述的行为相匹配。
解决方案是创建一个 jaas 配置文件并使用上述 属性 指定该文件。在所述 jaas.conf 文件中,设置 doNotPrompt=true
.
示例:
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true
useTicketCache=true
renewTGT=true
doNotPrompt=true
useKeyTab=false
storeKey=true
debug=true
;
};
主要讨论在 Krb5LoginModule
的 JavaDocs 中这里有一些额外的信息:http://cr.openjdk.java.net/~weijun/special/krb5winguide-2/raw_files/new/kwin