谷歌的Chrome和IE等应用程序可以透明地处理Kerberos身份验证; 但是,我无法找到一个"简单"的Java解决方案来匹配这种透明度.我发现的所有解决方案都需要存在krb5.conf文件和login.conf文件,而上述应用程序似乎需要这些文件.
使用Kerberos SSO功能构建Java应用程序的最佳方法是什么?
[更新]:要明确我需要一个CLIENT端解决方案来创建不验证它们的票证.此外,似乎SPNEGO是默认的"包装器"协议,最终将委托给Kerberos,但我也需要能够处理SPNEGO协议.
Mal*_*ith 15
现在有一个使用Apache HTTP Components Client 4.5或更高版本的简单解决方案.这在4.5中仍然标记为实验性,因此您的milage可能会有所不同,但在企业环境中这对我来说很好.
除了HC 4.5客户端jar之外,您还需要在类路径中使用httpclient-win,jna和jna-platform jar,如http-component-client所提供的.然后,您构建一个启用Kerberos的HC客户端,如下所示:
CloseableHttpClient httpclient = WinHttpClients.createDefault();
Run Code Online (Sandbox Code Playgroud)
或者使用构建器:
HttpClientBuilder clientBuilder = WinHttpClients.custom();
Run Code Online (Sandbox Code Playgroud)
然后可以在构建客户端之前根据需要对其进行自定义:
CloseableHttpClient client = clientBuilder.build();
Run Code Online (Sandbox Code Playgroud)
此解决方案无需任何外部配置即可运行,最重要的是解决了内置JRE机制在Windows 7+上具有本地管理员权限的用户中断的问题.这是可能的,因为Kerberos票证是通过JNA直接从SSPI API检索的,而不是通过JRE提供的GSSAPI.
来自http-components团队的示例代码
Daniel Doubrovkine Timothy Wall 和Ryan McKinley的出色工作使这一切成为可能
Aru*_*yal 10
添加到David Roussels关于url特定基于http的kerberos身份验证的答案: -
您的代码工作的原因是因为您的目标SPN(服务器端主体)配置为HTTP /serverhostname.realm.com@DOMAIN.COM.在这种情况下,它将起作用,因为您没有明确设置令牌.URLConnection在内部使用该SPN设置令牌
1执行步骤(来自我之前的答案)以获得主题
2使用gss api init sec context生成上下文令牌.这一步有很多教程
3 Base 64编码令牌
4将令牌附加到urlconnection: -
URL url = new URL("http://myhost/myapp")
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); =
urlConn.setRequestProperty("Authorization", "Negotiate " + encodedToken);
Run Code Online (Sandbox Code Playgroud)
5实施特权行动: -
//this internally calls the getInputStream
public class PrivilegedGetInputStream implements PrivilegedExceptionAction<InputStream>
Run Code Online (Sandbox Code Playgroud)
6将整个东西包裹在Subject.doAs中
//use prev answer instructions to get subject
Subject.doAs(subject, new PrivilegedGetInputStream(urlConnection)
Run Code Online (Sandbox Code Playgroud)
Oracle有一个使用Java的SaslClient的例子.我不是一名Java程序员,但是当我向某个人指出这一点时,他们能够很快地使它工作.它可能仍然需要某处的"conf"文件(nb Kerberos使用环境变量,通常以KRB5_开头,以了解在哪里查找此类文件).另请注意,Kerberos本身不包含任何类型的传输 - 您的应用程序需要知道如何以服务器期望的方式发送和接收Kerberos有效负载(这取决于您尝试进行身份验证的服务器).
编辑:你编辑了你的问题,所以这里有一个与Java中的SPNEGO相关的链接,可能有一些用处:http: //download.oracle.com/javase/6/docs/technotes/guides/security/jgss/lab/part5 html的
你实际上不需要做任何事情.在Java 6中,在Windows客户端计算机上,您可以执行以下操作:
new URL("http://myhost/myapp").openStream();
Run Code Online (Sandbox Code Playgroud)
协商身份验证才有效.至少它对我有用.我测试的服务器只支持Negotiate,而不支持NTLM auth.