【问题标题】:Unable to authenticate with apache http client 4.5 using kerberos ticket cache无法使用 kerberos 票证缓存向 apache http 客户端 4.5 进行身份验证
【发布时间】:2018-10-25 06:17:45
【问题描述】:

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

亲切的问候

【问题讨论】:

标签: java kerberos apache-httpclient-4.x apache-httpcomponents apache-httpclient-5.x


【解决方案1】:

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

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

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

在 Oracle JRE 的 Oracle 下载站点上。在 Additional Resources 下查看 JDK/JRE 8 的 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files

Oracle Java SE downloads

另见:Oracle Java SE 8 technotes jgss

注意:JDK 中的 JCE 框架包括对加密算法和应用程序可用的最大加密强度实施限制的能力。此类限制在“管辖政策文件”中指定。 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 的可能覆盖设置: https://stackoverflow.com/a/22492582/2824577

【讨论】:

  • 就是这样!我安装了已安装的打开 jdk,但我的项目使用的 oracle jdk 没有
【解决方案2】:

嗯...

默认主体:dragomira@MY_DOMAINE.COM

DEBUG 客户端主体是 dragomira@MY_DOMANIN.COM

域名?

【讨论】:

    【解决方案3】:

    我在 Spring Boot 应用程序中做同样的事情。我可以使用缓存票 (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);
    
    
        }
    

    【讨论】:

      猜你喜欢
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 2014-08-23
      • 2021-09-11
      • 1970-01-01
      相关资源
      最近更新 更多