首页 > 解决方案 > 无法使用 kerberos 票证缓存向 apache http 客户端 4.5 进行身份验证

问题描述

我正在对经过 kerberos 身份验证的 REST 服务执行 https 请求。如果我使用密钥表,一切都很好。但是,我有一个要求,即我应该使用 kerberos 票证缓存文件,该文件是在使用密码登录工作站时创建的。

我将用 MY_DOMAINE.COM 替换域

所以,klist 显示:

Ticket cache: FILE:/tmp/krb5cc_210007
Default principal: dragomira@MY_DOMAINE.COM

Valid starting     Expires            Service principal
05/15/18 07:21:51  05/15/18 17:21:51  krbtgt/MY_DOMAINE.COM@MY_DOMAINE.COM
        renew until 05/22/18 06:18:22

像这样使用 curl 可以正常工作:

curl -k --negotiate -u :  'my_url' -v

现在,让我们回到代码。我的 login.conf 是这样的:

com.sun.security.jgss.login {
  com.sun.security.auth.module.Krb5LoginModule required
  client=TRUE
  doNotPrompt=true
  useTicketCache=true;
};

com.sun.security.jgss.initiate {
  com.sun.security.auth.module.Krb5LoginModule required
  client=TRUE
  doNotPrompt=true
  useTicketCache=true;
};

com.sun.security.jgss.accept {
  com.sun.security.auth.module.Krb5LoginModule required
  client=TRUE
  doNotPrompt=true
  useTicketCache=true;
};

为 kerberos 设置的我的 http 客户端的相关 java 代码是:

try {
    SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build();
    HostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
    Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
            .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
            .build();
    Credentials dummyCredentials = new NullCredentials();
    CredentialsProvider credProv = new BasicCredentialsProvider();
    credProv.setCredentials(new AuthScope(null, -1, null), dummyCredentials);
    this.httpClient = HttpClientBuilder.create()
            .setDefaultAuthSchemeRegistry(authSchemeRegistry)
            .setDefaultCredentialsProvider(credProv)
            .setSSLContext(sslContext)
            .setSSLHostnameVerifier(hostnameVerifier)
            .build();
} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
    throw new RuntimeException(e.getMessage(), e);
}

在此之前,我正在设置这些 java 属性:

java.security.auth.login.config=/home/dragomira/kerberos/login.conf
java.security.krb5.conf=/etc/krb5.conf
sun.security.krb5.debug=true
javax.security.auth.useSubjectCredsOnly=false

kerberos 日志的输出是:

从 Java 配置加载

>>>KinitOptions cache name is /tmp/krb5cc_210007
>>>DEBUG <CCacheInputStream>  client principal is dragomira@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> server principal is krbtgt/MY_DOMANIN.COM@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> key type: 18
>>>DEBUG <CCacheInputStream> auth time: Tue May 15 06:18:22 EDT 2018
>>>DEBUG <CCacheInputStream> start time: Tue May 15 07:21:51 EDT 2018
>>>DEBUG <CCacheInputStream> end time: Tue May 15 17:21:51 EDT 2018
>>>DEBUG <CCacheInputStream> renew_till time: Tue May 22 06:18:22 EDT 2018
>>> CCacheInputStream: readFlags()  FORWARDABLE; RENEWABLE; INITIAL; PRE_AUTH;
>>>DEBUG <CCacheInputStream>  client principal is dragomira@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> server principal is HTTP/configuration.prd.int.MY_DOMANIN.COM@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> key type: 23
>>>DEBUG <CCacheInputStream> auth time: Tue May 15 06:18:22 EDT 2018
>>>DEBUG <CCacheInputStream> start time: Tue May 15 07:57:49 EDT 2018
>>>DEBUG <CCacheInputStream> end time: Tue May 15 17:21:51 EDT 2018
>>>DEBUG <CCacheInputStream> renew_till time: Tue May 22 06:18:22 EDT 2018
>>> CCacheInputStream: readFlags()  FORWARDABLE; RENEWABLE; PRE_AUTH;
>>> unsupported key type found the default TGT: 18

因此,在我看来,票据已被读取,但没有从中提取凭据,因为我最终收到 401。

为了使用票证,我必须对 apache http 客户端 4.5 做一些特别的事情吗?

亲切的问候

标签: javakerberosapache-httpclient-4.xapache-httpcomponentsapache-httpclient-5.x

解决方案


基于错误: unsupported key type found the default TGT: 18

类型 18 = aes-256-cts-hmac-sha1-96(请参阅IANA Kerberos 参数

我认为您正在使用具有有限强度 JCE 策略的 JRE,并且必须设置无限强度 JCE 策略。

在 Oracle JRE 的 Oracle 下载站点上。检查附加资源下的Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8

Oracle Java SE 下载

另请参阅:Oracle Java SE 8 技术说明 jgss

注意:JDK 中的 JCE 框架包括对应用程序可用的加密算法和最大加密强度实施限制的能力。此类限制在“管辖政策文件”中指定。Java SE 中捆绑的管辖策略文件限制了最大密钥长度。因此,要使用 AES256 加密类型,您需要安装无限制版本的 JCE 加密策略,以允许使用 256 位密钥的 AES。

测试您的政策(来源):

jrunscript -e 'print (javax.crypto.Cipher.getMaxAllowedKeyLength("AES") >= 256);'

从 2018 年初开始,所有受支持版本的 Oracle JDK 都开始提供默认的无限强度 JCE 策略:

https://bugs.openjdk.java.net/browse/JDK-8189377

另请参阅这些有趣的反射解决方法,以及 JRE9 的可能覆盖设置: https ://stackoverflow.com/a/22492582/2824577


推荐阅读