无法使用kerberos票证缓存使用apache http client 4.5进行身份验证

adr*_*mir 8 java kerberos apache-httpcomponents apache-httpclient-4.x apache-httpclient-5.x

我正在对kerberos认证的REST服务执行https请求.如果我使用keytab,一切都很好.但是,我要求我应该使用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
Run Code Online (Sandbox Code Playgroud)

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

curl -k --negotiate -u :  'my_url' -v
Run Code Online (Sandbox Code Playgroud)

现在,让我们回到代码.我的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;
};
Run Code Online (Sandbox Code Playgroud)

我的http客户端的相关java代码是针对kerberos的,它是:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

所以在我看来,票据被读取但是从最后收到401以来没有从中提取凭证.

我必须为apache http client 4.5做些特别的事情才能使用票证吗?

亲切的问候

use*_*737 3

根据错误: unsupported key type found the default TGT: 18

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

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

在 Oracle 下载站点上获取 Oracle JRE。检查“其他资源”下的JDK/JRE 8 的 Java 加密扩展 (JCE) 无限强度管辖策略文件

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);'
Run Code Online (Sandbox Code Playgroud)

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

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

另请参阅这些有趣的反射解决方法以及 JRE9 的可能覆盖设置: /sf/answers/1574480771/

  • 就是这样!我安装了 open jdk,其中安装了它们,但我的项目使用了 oracle jdk,但没有安装 (2认同)