当Java不应该使用';T

当Java不应该使用';T,java,authentication,kerberos,spnego,gss,Java,Authentication,Kerberos,Spnego,Gss,我们有一个可以与外部服务对话的服务器端应用程序。这取决于我们的配置,我们是否使用呼叫我们的用户的凭据、预先配置的凭据或根本不使用这些服务进行身份验证 外部服务可以使用HTTP协商身份验证。对于我们的自定义HTTP/WebDAV请求,我们使用ApacheHttpClient,在这里我们可以在自己的控制下处理凭据。但是对于JAX-WS调用(或由第三方LIB调用的普通HTTP URL),Java的HttpUrlConnection本身处理身份验证。这就是事情变得奇怪的地方 据推测,Java总是尝试使用

我们有一个可以与外部服务对话的服务器端应用程序。这取决于我们的配置,我们是否使用呼叫我们的用户的凭据、预先配置的凭据或根本不使用这些服务进行身份验证

外部服务可以使用HTTP协商身份验证。对于我们的自定义HTTP/WebDAV请求,我们使用ApacheHttpClient,在这里我们可以在自己的控制下处理凭据。但是对于JAX-WS调用(或由第三方LIB调用的普通HTTP URL),Java的HttpUrlConnection本身处理身份验证。这就是事情变得奇怪的地方

据推测,Java总是尝试使用来自当前主题的Kerberos凭据进行协商。那很好,而且有效。它也可以使用票证缓存(即kinit会话或系统会话,如果可以访问),但如果我正确阅读了文档(*),它应该只在两种情况下使用:

*)

  • javax.security.auth.useSubjectCredentialsOnly显式设置为false
  • 提供了一个自定义JAAS配置,它显式地将useTicketCache设置为true
  • 事实并非如此。在我们的可复制测试中,如果主题为空,则默认始终使用系统凭据。更糟糕的是,将useSubjectCredentialsOnly显式设置为true(应为默认值)不会更改此行为。到目前为止,我们找到的唯一解决方法是显式提供一个自定义JAAS配置,该配置将useTicketCache设置为false(这也是默认设置)

    在Krb5LoginModule中进行调试表明,除非我们配置此解决方案,否则登录模块实际上会使用useTicketCache=true调用

    我们可以在我们所有的Windows系统上复制它。看起来Linux可能运行良好,但我无法详细验证这一点(由于域问题)

    我看错文件了吗?或者Java实现中是否存在bug?还是我们的Windows系统不可靠


    似乎很不理想的是,我们必须告诉我们的客户始终配置一个解决方案,以防止Java使用服务用户而不是向我们的服务发送请求的用户的凭据秘密调用远程服务。

    至少在Linux上的Java 8 u 131代码中,我刚刚调试过,函数sun.security.jgss.GSSUtil.UseSubjectCredOnly(GSSCaller调用者)经过硬编码,如果调用者是HttpCaller的实例,则返回false


    对于其他类型的调用方,将检查javax.security.auth.UseSubjectCredOnly属性。

    您可能有兴趣阅读“Hadoop和Kerberos,大门之外的疯狂”,特别是该页面:(Web和REST”和“JAAS”部分也很严肃)。这并不能真正帮助我解决问题,但至少我可以告诉人们为什么上班这么复杂。顺便说一句,我认为
    useSubjectCredentialsOnly
    的默认值随着时间的推移发生了变化。而且整个Kerberos行为(JAAS和MIT Kerberos中)可能取决于您运行的操作系统(即Windows不同),问题是,(显然)错误的默认行为是useTicketCache困扰我的地方。但是UseSubjectCredentials似乎对我的用例没有任何影响,不管我将它设置为什么。另外,一篇关于Java在Windows上真正做了什么的有趣文章(可能是因为Active Directory SSO是房间里的一个非常大的大象,你不能假装忽略它)——请查看“初始凭据”>