我已经编写了一个在Windows下运行的简单JavaHTTP客户端。客户端与需要通过SPNego进行Kerberos身份验证的Web服务器进行通信。
我遇到了两个问题:
>
服务票证没有存储在我的凭据缓存中。执行请求后,我希望看到一个Kerberos服务票存储在我的凭据缓存下的C:\用户\
如果我在循环中运行100次以下的代码,它只运行n次(其中n是1到100之间的随机数)。失败的请求返回一条401错误消息,因为Java无法检索服务票证(请记住:由于我的应用程序不在请求之间存储服务票证,所以它会尝试为每个请求从TGT获取一个新的服务票证)。我已经在这个问题的底部添加了错误消息。
我在JDK的bin文件夹中通过kinit创建了一个TGT。以下代码段用于发出简单的GET请求:
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());
}
以下是我jaas.conf的内容(如下所述):
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false useTicketCache=true;
};
我用以下参数运行我的应用程序:
-Djava.security.auth.login.config=D:\jaas.conf
-Dsun.security.krb5.debug=true
-Djavax.security.auth.useSubjectCredsOnly=false
我不是在用krb5。ini,因为我的客户端从域配置中获得了正确的KDC。
我可以通过以下命令为我的凭据缓存生成TGT:
C:\Program Files\Java\jdk1.8.0_77\bin>kinit
Password for <user>@<domain>:
New ticket is stored in cache file C:\Users\<user>\krb5cc_<user>
最后,这里是授权失败时的异常和Kerberos调试输出(参考问题2)。请注意,ctime显然是错误的。我有过许多不同的尝试,ctime的时间跨度从1970年到2040年不等。有趣的是,并不是每个请求都会发生这种情况。
>>>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/<spn>@<domain>
msgType is 30
KrbException: Request is a replay (34) - PROCESS_TGS
我已经尝试过使用
Subject.doAs
来处理JAAS,但是这会导致同样的问题。通过浏览器访问服务器运行良好(尽管这不是可比性,因为浏览器使用的是Windows本地凭据缓存AFAICT)。
对于如何调试这样的问题,我非常感谢您的建议。
编辑:通过
KRB5CCNAME
环境变量显式指定凭据缓存的路径不会更改行为。TGT似乎是从凭据缓存中获取的,但服务票证没有存储在那里。
JAAS不会将票据持久化到缓存中,您必须使用kinit或通过代码以编程方式调用kinit代码。我在这里写了一个关于这个问题的问答。
关于偶尔出现的随机时间值:我们发现在krb5中设置
udp_preference_limit=1
。ini解决了这个问题。这有效地告诉Kerberos始终尝试先使用TCP发送包。显然,切换到UDP时存在问题(不确定是UDP还是协议之间的切换)。
关于缓存
kinit
版本显然使用了Linux标准,即文件:
API:
可能的解决方法:在Windows上使用Kerberos UI创建TGT,或者通过设置KRB5CCNAME
强制Java使用文件缓存。
参考:MIT Kerberos文档,尤其是关于硬编码默认值的最后一个链接
~~~~~~~
关于随机时间值
我们已经实现了Kerberos java客户端,它运行良好。然而,当kerberos票证过期时,Java客户端应用程序会在控制台中请求用户名,这反过来会使应用程序挂起。在SoapUI等工具中,我们观察到当Kerberos票证过期时,系统抛出未经授权的错误。我们希望实现类似的行为,即如果Kerberos票证过期,则应抛出未经授权的错误,而不是等待用户输入凭据。请帮忙。 为Kerberos测试设置客户
我正在运行JMeter,它依赖于JDK 1.8的Krb5LoginMoules。 在我看来,不能跨多个请求维护kerberos会话。这将导致HTTP 401和每次请求前重新握手。 我正试图重现一个有严重间歇性性能问题的生产环境,我希望在测试中包括Kerberos/SSO身份验证,但我无法将其设置为像使用REST服务器的Windows客户端那样运行。 REST服务器向数百个Excel加载项客户端提供
问题内容: 有谁知道如何使用Java GSS-API从密钥分发中心(KDC)获取服务票证? 我有一个胖客户端应用程序,该应用程序首先使用Krb5LoginModule通过JAAS进行身份验证以从票证缓存中获取TGT(背景:Windows例如使用kerberos实现,并将票证授予票证存储在安全的存储区域中)。从LoginManager中,我获得包含TGT的Subject对象。现在,我希望当我为我的服
任务:将Kerberos active directory身份验证添加到不安全的报告和数据操作桌面应用程序。此应用程序是。。。 用Stackless Python 2.7编写 使用Twisted进行客户端-服务器交互 客户端编译为exe并在Windows上运行 服务器在Linux(红帽)上运行 目前,我们从用户帐户中提取Windows网络ID(登录名)并传递到服务器,服务器会查找用户配置为具有的权
websocket客户端(使用Autobahn/Python和Twisted)需要连接到websocket服务器:客户端需要向服务器提供其客户端证书,客户端需要检查服务器的证书。例如,这些证书是在Kubernetes minikube安装过程中创建的。特别地: 服务器证书(据我所知为X509格式) 客户端证书~/。minikube/客户。按键 我已经检查过,我可以成功地使用这些证书密钥使用发出库伯
我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se