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

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

问题描述:

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

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客户端将在与IIS服务位于同一Active Directory网络上的Windows计算机上运行(即,我每天登录的帐户都可以访问该服务).我希望我的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:

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);

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

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.

我应该使用什么代码,以便它无需登录用户名和密码即可与登录用户的凭据连接?这可能吗?

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?

自从我使用Axis已有几年了-那时,Axis依赖于Apache commons httpclient3.从阅读一些邮件列表来看,它看起来像情况仍然如此.(如果没有,最后一段应该提供一些可喜的缓解.)

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.)

Apache commons httpclient 3不支持通过HTTP的集成Windows身份验证"(又名带有Kerberos的协商身份验证机制,又名"SPNEGO".)实际上,它不支持NTLMv2,仅支持NTLMv1.'将无法对许多需要NTLMv2且未经修改的IIS服务器进行身份验证.

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.

尽管公认的解决方案比较笨拙,但我认为最好的选择是创建一个新的AuthScheme,该新的AuthScheme调用Windows SSPI库进行身份验证.不幸的是,您将需要使用JNI来执行此操作.幸运的是,AuthScheme准备做一个基于会话的质询-响应身份验证模式(SPNEGO在这方面已经支持NTLM,这已得到支持.)基本上,您将对输入和输出字节缓冲区进行base64编码,以进行本机InitializeSecurityContext调用..我承认,编写代码很麻烦,但是我可以确认它确实可以让您对IIS服务器执行集成Windows身份验证.

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.

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

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

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

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.

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

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.