无法使用 kerberos 票证缓存对 apache http 客户端 4.5 进行身份验证

Unable to authenticate with apache http client 4.5 using kerberos ticket cache

我正在对 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 做一些特殊的事情才能使用 ticket tacke 吗?

亲切的问候

嗯...

默认主体:dragomira@MY_DOMAINE.COM

DEBUG client principal is dragomira@MY_DOMANIN.COM

域?

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

类型 18 = aes-256-cts-hmac-sha1-96(参见 IANA Kerberos Parameters

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

在 Oracle JRE 的 Oracle 下载站点上。在其他资源下查看 Java 密码学扩展 (JCE) 无限强度管辖政策文件 JDK/JRE 8

Oracle Java SE downloads

另请参阅:Oracle Java SE 8 technotes jgss

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

正在测试您的政策(source):

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

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

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

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

我在 spring 引导应用程序中做同样的事情。我能够使用缓存票证 (users/conf/krb5_xyz) 进行休息调用并正确验证。

我的工作客户:

public class Test {

    public static void main(String[] args) {


        Map<String, Object> loginOption = new HashMap<>();
        loginOption.put("refreshKrb5Config","true");
        loginOption.put("useTicketCache", "true");
        loginOption.put("ticketCache","h:/config/krb5cc_xyz");
        loginOption.put("doNotPrompt","true");
        loginOption.put("debug","true");

  /* 
option 1 : using keytab

KerberosRestTemplate restTemplate = new KerberosRestTemplate("C:\Users\xyz\kerberos\kerberos\src\main\resources\xyz.keytab", "wdd@sd.sd.sd");*/

/* option 2: using cache */
       KerberosRestTemplate restTemplate = new KerberosRestTemplate(null , "-",loginOption);
        String response = restTemplate.getForObject("http://host:13080/xyz",String.class);
        System.out.println("Result"+response);


    }