Tag: gssapi

GSSException:修改了消息流(41)

我正在使用森林架构中的LDAP(所有服务器和我的服务器都是Windows)。 我使用NTLM身份validation绑定到AD。 我有一个JAVA代码,可以对LDAP服务器执行操作。 代码被包装为tomcat servlet。 直接运行JAVA代码(只是作为应用程序执行LDAP身份validation代码)时,绑定对本地域(本地域=我登录到Windows,并与此域的用户运行此进程)和外部域都有效。 当将JAVA代码作为servlet运行时,绑定工作并从一个域validation用户,但如果我尝试从其他域validation用户,则无法正常工作,它将无法工作(仅当我重新启动tomcat时它才会起作用)。 我得到一个例外: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))]] 我会提到它是相同的代码,具有相同的配置和相同的krb5文件。 编辑:更多信息: 这是我的代码: public void func(String realm, String kdc) { try { URL configURL = getClass().getResource(“jaas_ntlm_configuration.txt”); System.setProperty(“java.security.auth.login.config”, configURL.toString()); System.setProperty(“java.security.krb5.realm”, realm); System.setProperty(“java.security.krb5.kdc”,kdc); // If the application is run on NT rather than […]

Java GSS-API服务票证未使用Java保存在凭据高速缓存中

我使用GSS-API创建了2个演示Kerberos客户端。 一个在Python3中,第二个在Java中。 两个客户端似乎大致相同,并且两者都“起作用”,因为我获得了我的Java GSS-API服务主体接受的服务票证。 但是在测试时我注意到Python客户端将服务票据保存在kerberos凭证缓存中,而Java客户端似乎没有保存票证。 我使用“klist”来查看凭证缓存的内容。 我的客户使用FreeIPA作为Kerberos环境在Lubuntu 17.04虚拟机上运行。 我正在使用OpenJDK 8 u131。 问题1: Java GSS-API是否不保存凭证缓存的服务票证? 或者我可以更改我的代码吗? 问题2:服务票据是否未保存到缓存这一事实是否有任何缺点? 我的假设是缓存的服务票据减少了与KDC的交互,但评论了如何使用Windows Java客户端保存Kerberos服务票证? 建议事实并非如此,但是这个Microsoft技术说明“每次想要访问这个特定服务器时,客户端都不需要返回KDC”。 问题3:来自python客户端的缓存服务票证在几分钟后消失 – 在到期日之前很久。 是什么导致他们消失? Python代码 #!/usr/bin/python3.5 import gssapi from io import BytesIO server_name = ‘HTTP/app-srv.acme.com@ACME.COM’ service_name = gssapi.Name(server_name) client_ctx = gssapi.SecurityContext(name=service_name, usage=’initiate’) initial_client_token = client_ctx.step() Java代码 System.setProperty(“java.security.krb5.conf”,”/etc/krb5.conf”); System.setProperty(“javax.security.auth.useSubjectCredsOnly”,”false”); GSSManager manager = GSSManager.getInstance(); GSSName clientName; GSSContext context […]

人们如何让Java SPNEGO客户端在Windows中运行?

要在Windows上使用Java进行客户端HTTP SPNEGO身份validation,您需要设置Windows注册表项allowtgtsessionkey 。 这是有据可查的。 我不明白的是人们如何解决这个问题? 大多数企业站点永远不会接受在Windows中为了单个软件而更改此注册表项。 如果需要在组织中的每个工作站上更改它,请考虑一下麻烦。 但这只是理论,因为我到目前为止还无法说服我们的任何客户更改此注册表项。 我不怪他们。 大多数企业管理员会认为这样可以放松安全性并因此反对它。 我已经读过: 在Java或命令行工具中是否有办法使用本机SSPI API获取服务的Kerberos票证? 但它现在已经很老了。 所以我真的,真的不明白人们如何使Windows + Java客户端+ Kerberos可以在除大学环境,家庭用户等之外的任何地方工作。 我从公司管理员那里得到的问题是“当IE和Firefox等应用程序在没有设置此密钥的情况下执行SPNEGO时,我们为什么需要设置此注册表项?”。 好吧,我知道答案是什么。 这是因为(很可能)IE和Firefox等应用程序基于Windows本机GSS API(SSPI),而Sun的Java使用自己的实现。 我假设使用像WAFFLE这样的东西可以解决问题,但我赞成纯Java解决方案。 我还假设使用基于Java的解决方案(如Spring安全性或Apache HttpClient)无济于事,因为它们都会遇到这个问题。 任何帮助或指示将不胜感激。 更新1 : 我发现Oracle的bug数据库中有一个RFE 。 还有一个Oracle员工就此问题提交的补丁以及有关此function的JDK邮件列表的讨论 。 除了我能理解的这一点,在目前的Java 7中没有这个function,甚至不是实验性的。 对? 更新2 : 现在问题在OpenJDK Security Dev邮件列表上再次存在 。

使用GSSManagervalidationKerberos票证

我有以下代码: public static void main(String args[]){ try { //String ticket = “Negotiate YIGCBg…==”; //byte[] kerberosTicket = ticket.getBytes(); byte[] kerberosTicket = Base64.decode(“YIGCBg…==”); GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null); context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length); String user = context.getSrcName().toString(); context.dispose(); } catch (GSSException e) { e.printStackTrace(); } catch (Base64DecodingException e) { e.printStackTrace(); } } 当然它失败了。 这是例外: GSSException: Defective token detected (Mechanism […]

使用JSch 跳过Kerberos身份validation提示

我在下面的Ssh Java类中使用Connect()方法,以便使用SSH(JSch)连接到服务器并在服务器中运行命令。 问题是当运行Connect() ,服务器会提示下一条消息: Kerberos username [********]: Kerberos password for ********: 为了继续运行,我需要手动按两次Enter键,一个用于用户名,一个用于密码。 我试图添加下一个代码: // Press ENTER Robot r = new Robot(); r.keyPress(KeyEvent.VK_ENTER); r.keyRelease(KeyEvent.VK_ENTER); 但是这段代码只适用于用户名,我无法弄清楚当服务器要求输入密码时如何自动按ENTER键。 到目前为止,我已经尝试将另一个代码片段作为上面显示的代码片段 session.connect(); 线。 package ConnectSSH; import java.awt.Robot; import java.awt.event.KeyEvent; import java.io.*; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UserInfo; public class Ssh{ private static final String user = “********”; private static […]