java - 无法使用 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 做一些特别的事情吗?
亲切的问候
解决方案
基于错误:
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 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
推荐阅读
- php - Which PHP exception to throw when last method in chain requires other method called first
- loops - 带有循环的 PHP 邮件程序和 FPDF 附件 - 脚本在第一次运行后停止
- json - Jq - 使用 jq 将 JSON 转换为另一种 JSON 格式
- javascript - 通过键和交换值搜索两个对象
- javascript - 如何使用 ASP.NET 项目为 scss 和 bootstrap 配置 webpack?
- angular - 如何在 Internet Explorer 上使用 Angular 解决法语特殊字符的问题?
- c++ - 反转字符串 C++
- c++ - 默认情况下不使用 std::next 的范围循环?
- azureservicebus - 如何在消息属性上创建服务总线主题订阅过滤器?
- python - 过滤列表以获取其最大值