java票证管理办法,如何使用Windows Java客户端保存Kerberos服务票证?

I've written a simple Java HTTP Client that is running under Windows. The client communicates with a web server which requires Kerberos authentication through SPNego.

I'm experiencing two problems:

The service ticket is not stored in my credentials cache. After performing a request, I expected to see a Kerberos Service Ticket stored in my credentials cache under C:\Users\\krb5cc_ - was I wrong to assume that Java stores service tickets in the credential cache? I'd like to reuse a Service Ticket obtained in Client A for requests in Client B (where both Clients are Java applications on the same machine). Is this possible with Java?

If I run the code below one hundred times in a loop, it only works n-times (where n is a random number between 1 and 100). The failing request returns a 401 error message, because Java wasn't able to retrieve a Service ticket (remember: since my application doesn't store service tickets between requests, it tries to obtain a new service ticket from the TGT for every request). I've added the error message to the bottom of this question.

I've created a TGT via kinit in my JDK's bin folder. The following code snippet is used for making simple GET requests:

static void testJavaHttpKerberosAuthentication() throws IOException {

URL obj = new URL(URI);

HttpURLConnection con = (HttpURLConnection) obj.openConnection();

int responseCode = con.getResponseCode();

System.out.println("\nSending 'GET' request to URL : " + URI);

System.out.println("Response Code : " + responseCode);

BufferedReader in = new BufferedReader(

new InputStreamReader(con.getInputStream()));

String inputLine;

StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {

response.append(inputLine);

}

in.close();

//print result

System.out.println(response.toString());

}

Here's the content of my jaas.conf (as described here):

com.sun.security.jgss.krb5.initiate {

com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false useTicketCache=true;

};

I'm running my application with the following parameters:

-Djava.security.auth.login.config=D:\jaas.conf

-Dsun.security.krb5.debug=true

-Djavax.security.auth.useSubjectCredsOnly=false

I'm not using as a krb5.ini since my client obtains the correct KDC from the domain configuration.

I can generate a TGT for my credentials cache via the following command:

C:\Program Files\Java\jdk1.8.0_77\bin>kinit

Password for @:

New ticket is stored in cache file C:\Users\\krb5cc_

And finally, here's the exception and Kerberos Debug Output for the case where authorization fails (ref. Problem 2). Please note that ctime is obviously wrong. I've had many different attempts and the timespan for the ctime ranges from 1970 to 2040. Interestingly enough, this doesn't happen for every request.

>>>KRBError:

cTime is Wed Jun 07 12:24:03 CEST 2017 1496831043000

sTime is Tue Mar 29 16:38:24 CEST 2016 1459262304000

suSec is 283371

error code is 34

error Message is Request is a replay

sname is HTTP/@

msgType is 30

KrbException: Request is a replay (34) - PROCESS_TGS

I've already tried to work with JAAS using Subject.doAs, but this is causing the same problems. Accesing the server via the browser works fine (although this is not comparable, as the browsers are using the Windows native credentials cache AFAICT).

I'd be thankful for some advice on how to debug a problem like this.

EDIT: Specifiying the path to the credentials cache via the KRB5CCNAME environment variable explicitly, does not change the behavior. It seems like the TGT is obtained from the Credentials Cache but Service Tickets are not stored there.

解决方案

JAAS is not going to persist tickets into the cache, you have to use kinit or invoke kinit code programmatically by your code.

I have wrote a SO question/answer on this problem here.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值