11

我有一个使用 spring-security kerberos 扩展的工作应用程序,在 jboss 上运行,运行 java 6。

我正在将我的 jvm 从 java 6 升级到 java 7。当我这样做时,使用在 java 6 上工作的相同代码库和相同的 keytab,我现在在使用 java 7 时收到错误。

我一直收到:java.security.PrivilegedActionException:GSSException:在 GSS-API 级别未指定失败(机制级别:无效参数 (400) - 找不到适当类型的密钥来解密 AP REP - RC4 与 HMAC)

我尝试使用其他论坛中描述的不同 /crypto 选项重新生成密钥表,但无济于事。

我已经调试了 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 的,并且有效。

亚伦

4

3 回答 3

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);
于 2013-02-04T21:10:12.097 回答
1

Here are two potential issues that might be affecting you:

  1. Java 7 appears to switch the default encryption type order. Details:

  2. You did't say what specific version of JDK 7 you are using, but there was a bug in earlier versions of JDK 7 that prevented loading keytab files via "file:" URLs:

Another user on SO worked around the last issue by modifying Spring source:

于 2013-01-24T01:44:46.640 回答
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), };
        }

希望这可以帮助您解决问题。

于 2013-02-01T19:50:08.390 回答