Java 客户端调用 Windows 集成身份验证 Web 服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5905390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:22:22  来源:igfitidea点击:

Java client call to Windows Integated Authentication web service

javasecurityaxis2windows-authenticationcredentials

提问by Shawn

I am writing a Java 1.5+ client that needs to fetch data from an IIS-hosted web service. I created a new web service client in Eclipse and used the Java Proxy client type and Apache Axis2 web service runtime when generating the client proxy. The web service itself runs on Windows 2003 and security is set to use only Windows Integrated Authentication. I have found many articles online that show how to connect successfully from a Java client to this IIS service, but everything I have seen seems to require that I put the username and password in my Java client code somewhere.

我正在编写一个 Java 1.5+ 客户端,它需要从 IIS 托管的 Web 服务中获取数据。我在 Eclipse 中创建了一个新的 Web 服务客户端,并在生成客户端代理时使用了 Java 代理客户端类型和 Apache Axis2 Web 服务运行时。Web 服务本身在 Windows 2003 上运行,安全性设置为仅使用 Windows 集成身份验证。我在网上找到了很多文章,展示了如何从 Java 客户端成功连接到这个 IIS 服务,但我所看到的一切似乎都要求我将用户名和密码放在我的 Java 客户端代码中的某处。

My Java client will run on a Windows machine that is on the same Active Directory network that the IIS service is on (i.e. the account I log in with each day can access the service). I want my Java client to run in the context of the logged-in user without me needing to put in my login credentials in the code. Here is my current code, which works, yet requires me to put a user name and password in the code:

我的 Java 客户端将在 Windows 机器上运行,该机器与 IIS 服务位于同一 Active Directory 网络(即我每天登录的帐户可以访问该服务)。我希望我的 Java 客户端在登录用户的上下文中运行,而无需在代码中输入我的登录凭据。这是我当前的代码,它有效,但需要我在代码中输入用户名和密码:

final NTCredentials nt = new NTCredentials("my_username", "my_password", "", "my_domain");
        final CredentialsProvider myCredentialsProvider = new CredentialsProvider() {
            public Credentials getCredentials(final AuthScheme scheme, final String host, int port, boolean proxy) throws CredentialsNotAvailableException {
                return nt; 
            }
        };

        DefaultHttpParams.getDefaultParams().setParameter("http.authentication.credential-provider", myCredentialsProvider);

But I really don't want to have to put the username and password in the code--I want it to run using the credentials of the logged-in Windows user that is running the Java client.

但我真的不想在代码中输入用户名和密码——我希望它使用运行 Java 客户端的登录 Windows 用户的凭据运行。

What code should I use so it will connect with the logged-in user's credentials without needing to specify the user name and password? Is this possible?

我应该使用什么代码才能连接到登录用户的凭据而无需指定用户名和密码?这可能吗?

回答by Edward Thomson

It's been a few years since I've used Axis - then, Axis depended on Apache commons httpclient 3. From reading some mailing lists, it looks like this is still the case. (If not, the last paragraph should provide some welcome relief.)

自从我使用 Axis 已经有几年了 - 然后,Axis 依赖于 Apache commons httpclient 3。从阅读一些邮件列表来看,情况似乎仍然如此。(如果没有,最后一段应该提供一些受欢迎的缓解。)

Apache commons httpclient 3 has no support for "Integrated Windows Authentication" over HTTP (aka the Negotiate authentication mechanism with Kerberos, aka "SPNEGO".) In fact, it doesn't support NTLMv2, only NTLMv1, which means that you'll not be able to authenticate to many IIS servers that require NTLMv2 without modifications.

Apache commons httpclient 3 不支持通过 HTTP 的“集成 Windows 身份验证”(又名 Kerberos 协商身份验证机制,又名“SPNEGO”。)事实上,它不支持 NTLMv2,只支持 NTLMv1,这意味着你不会无需修改即可对许多需要 NTLMv2 的 IIS 服务器进行身份验证。

Although admittedly a heavy-handed solution, I think that your best bet would be to create a new AuthScheme that calls the Windows SSPI libraries to do authentication. Unfortunately, you'll need to use JNI to do this. Fortunately, AuthScheme is prepared to do a session-based challenge-response authentication pattern (SPNEGO is similar in that regard to NTLM, which is already supported.) Basically, you'll base64 encode the input and output byte buffers to the native InitializeSecurityContext call. It's tedious to write, I admit, but I can confirm that it does let you perform Integrated Windows Authentication to an IIS server.

虽然无可否认是一个严厉的解决方案,但我认为最好的办法是创建一个新的 AuthScheme,它调用 Windows SSPI 库来进行身份验证。不幸的是,您需要使用 JNI 来执行此操作。幸运的是,AuthScheme 准备执行基于会话的质询-响应身份验证模式(SPNEGO 在这方面类似于已经支持的 NTLM。)基本上,您将对输入和输出字节缓冲区进行 base64 编码到本机 InitializeSecurityContext 调用. 写起来很乏味,我承认,但我可以确认它确实让您对 IIS 服务器执行集成 Windows 身份验证。

(Unfortunately, if you need your client to be cross-platform, you'll also need to write the necessary GSSAPI code on Unix.)

(不幸的是,如果你需要你的客户端是跨平台的,你还需要在 Unix 上编写必要的 GSSAPI 代码。)

Another option is to write a new AuthScheme that uses Java's Kerberos libraries (JAAS). I don't know much about these, to be honest, because it requires separate configuration from your system kerberos libraries. Ie, on Windows you'll have to write some kerberos configuration files that point to your Active Directory server. Which, in my opinion, doesn't really sound all that "integrated". If you're distributing your software to customers and they expect it to "just work", this may not work out for you. Plus, although JAAS has been around for a while, I believe that early versions lacked some authentication mechanisms that were required to talk to Active Directory, so I think you'll require a Java 6 runtime.

另一种选择是编写一个使用 Java 的 Kerberos 库 (JAAS) 的新 AuthScheme。老实说,我对这些知之甚少,因为它需要与您的系统 kerberos 库分开配置。即,在 Windows 上,您必须编写一些指向 Active Directory 服务器的 kerberos 配置文件。在我看来,这听起来并不是那么“集成”。如果您将软件分发给客户并且他们希望它“正常工作”,那么这可能对您不起作用。另外,虽然 JAAS 已经存在一段时间了,但我相信早期版本缺乏与 Active Directory 对话所需的一些身份验证机制,因此我认为您需要 Java 6 运行时。

Now, if I'm mistaken and you can use Axis2 with the new Apache http-components httpclient 4, then you're in much better shape. httpclient 4 supports SPNEGO using Java's Kerberos libraries, which means that once you don't have to write your own AuthScheme, you just need to configure your C:\WINDOWS\KRB5.INI and you should be able to take advantage of Integrated Windows Authentication. However, to avoid that manual step of having to configure JAAS, you'll still need to call the native SSPI methods.

现在,如果我弄错了,并且您可以将 Axis2 与新的 Apache http-components httpclient 4 一起使用,那么您的状态要好得多。httpclient 4 支持使用 Java 的 Kerberos 库的 SPNEGO,这意味着一旦您不必编写自己的 AuthScheme,您只需配置 C:\WINDOWS\KRB5.INI 并且您应该能够利用集成的 Windows 身份验证. 但是,为了避免必须配置 JAAS 的手动步骤,您仍然需要调用本机 SSPI 方法。

回答by jt.

The functionality that you are describing is not a feature of the OS, but of Internet Explorer. You should probably gain a better understanding of how "Windows Authentication" really works (aka NLTM HTTP Authentication). JCIFS is removing the ServletFilter that provides this functionality to servlet containers. However, their basic description of how NTLM HTTP Authentication worksis helpful.

您所描述的功能不是操作系统的功能,而是 Internet Explorer 的功能。您可能应该更好地了解“Windows 身份验证”的真正工作原理(又名 NLTM HTTP 身份验证)。JCIFS 正在删除为 servlet 容器提供此功能的 ServletFilter。但是,他们对 NTLM HTTP 身份验证如何工作基本描述很有帮助。

Once you understand the way the authentication works, you might be able to implement some sort of Axis plugin to provide the functionality.

一旦您了解了身份验证的工作方式,您就可以实现某种 Axis 插件来提供该功能。