我有一个使用spring-security kerberos扩展的工作应用程序,在jboss上运行,运行java 6.
我正在将jvm从java 6升级到java 7.当我这样做时,使用与java 6相同的代码库和相同的keytab,我现在在使用java 7时收到错误。< / p>
我一直收到: java.security.PrivilegedActionException:GSSException:在GSS-API级别未指定失败 (机制级别:无效参数(400) - 找不到合适类型的密钥用HMAC解密AP REP-RC4
我尝试使用其他论坛中描述的不同/加密选项重新生成密钥表无效。
我已经调试了java 7代码,实际上,处理启动时读取keytab的类从6更改为7.可能是因为我的keytab不再正确读入应用程序了吗?我在启动时使用Java6看到的一些调试消息在7中不再出现了,但我不知道这是设计还是表明还有其他内容在起作用?有没有其他人有问题从6升级到7并且他们的kerberos集成打破了他们?有什么建议吗?
使用spnego和kerberos调试登录进行启动时,我的日志显示:
2012-12-10 10:29:30,886 Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is jndi:/localhost/docfinity/WEB-INF/classes/config/common/security/http-docfinity.keytab refreshKrb5Config is false principal is HTTP/VMMSSDEV.TESTING.LOCAL@TESTING.LOCAL tryFirstPass is false useFirstPass is false storePass is false clearPass is false
2012-12-10 10:30:26,322 principal is HTTP/VMMSSDEV.TESTING.LOCAL@TESTING.LOCAL
2012-12-10 10:30:29,794 Will use keytab
2012-12-10 10:30:29,807 Ordering keys wrt default_tkt_enctypes list
2012-12-10 10:30:29,821 Config name: C:\Windows\krb5.ini
2012-12-10 10:30:29,827 Using builtin default etypes for default_tkt_enctypes
2012-12-10 10:30:29,832 default etypes for default_tkt_enctypes:
2012-12-10 10:30:29,837 17 aes128-cts-hmac-sha1-96
2012-12-10 10:30:29,839 16 des3-cbc-sha1-kd
2012-12-10 10:30:29,842 23 rc4-hmac
2012-12-10 10:30:29,846 1 des-cbc-crc
2012-12-10 10:30:29,849 3 des-cbc-md5
2012-12-10 10:30:29,851 .
2012-12-10 10:30:29,855 Commit Succeeded
另一个问题 - 你会看到它试图读取C:\ Windows \ krb5.ini。我的服务器上没有这样的文件。我需要一个吗?我也没有使用java 6,而且工作正常。
亚伦
答案 0 :(得分:2)
是的!我们修补了SunJaasKerberosTicketValidator看起来像这样,它起作用了:
String keyTabPath = this.keyTabLocation.getURL().toExternalForm();
String runtimeVersion = System.getProperty("java.version");
if (runtimeVersion.startsWith("1.7"))
{
LOG.info("Detected jdk 7. Modifying keytabpath");
if (keyTabPath != null)
{
if (keyTabPath.startsWith("file:"))
{
keyTabPath = keyTabPath.substring(5);
}
}
}
LOG.info("KeyTabPath: " + keyTabPath);
LoginConfig loginConfig = new LoginConfig(keyTabPath, this.servicePrincipal,
this.debug);
答案 1 :(得分:1)
以下是可能影响您的两个潜在问题:
Java 7似乎可以切换默认的加密类型顺序。详细说明:
您没有说明您正在使用的JDK 7的特定版本,但早期版本的JDK 7中存在一个错误,该错误阻止通过“file:”URL加载keytab文件:
SO的另一位用户通过修改Spring源来解决上一期的问题:
答案 2 :(得分:1)
将keyTabLocation对象更改为字符串。
So private String keyTabLocaiton.
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.servicePrincipal, "servicePrincipal must be specified");
Assert.notNull(this.keyTabLocation, "keyTab must be specified");
// if (keyTabLocation instanceof ClassPathResource) {
// LOG.warn("Your keytab is in the classpath. This file needs special protection and shouldn't be in the classpath. JAAS may also not be able to load this file from classpath.");
// }
LoginConfig loginConfig = new LoginConfig(this.keyTabLocation, this.servicePrincipal,
this.debug);
Set<Principal> princ = new HashSet<Principal>(1);
princ.add(new KerberosPrincipal(this.servicePrincipal));
Subject sub = new Subject(false, princ, new HashSet<Object>(), new HashSet<Object>());
LoginContext lc = new LoginContext("", sub, null, loginConfig);
lc.login();
this.serviceSubject = lc.getSubject();
}
同样在LoginConfig的位置,将isInitiator标志设置为true。
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("useKeyTab", "true");
options.put("keyTab", this.keyTabLocation);
options.put("principal", this.servicePrincipalName);
options.put("storeKey", "true");
options.put("doNotPrompt", "true");
if (this.debug) {
options.put("debug", "true");
}
options.put("isInitiator", "true");
//options.put("isInitiator", "false");
return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options), };
}
希望这可以帮助您解决问题。