通过具有 Windows (NTLM) 身份验证的代理访问具有基本身份验证的 Web 服务
我有一个使用基本身份验证的网络服务。我还有一个使用 Web 服务的 Windows 窗体应用程序。当它启动时,系统会要求用户提供凭据,然后在向服务发出任何请求时使用这些凭据。
问题是,该应用程序由公司网络内的客户端使用。他们的所有互联网流量都通过使用 Windows 身份验证的代理进行路由。我正在尝试将我的应用程序配置为在发出请求时正确使用该代理。
到目前为止,我的客户端应用程序的 app.config 中有这样的内容:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="mySoap" closeTimeout="00:02:00" openTimeout="00:02:00"
receiveTimeout="00:10:00" sendTimeout="00:02:00" allowCookies="false"
bypassProxyOnLocal="true" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="Windows"
realm="myrealm" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.myservice.com/service.asmx"
binding="basicHttpBinding" bindingConfiguration="mySoap"
contract="MyPublicService.mySoap" name="mySoap" />
</client>
</system.serviceModel>
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
您认为这会起作用吗?我无法轻易测试它。该应用程序和服务已经在没有代理的情况下进行了测试,它们工作得很好,我只需要正确配置代理即可。
理论上,此配置将确保所有请求都使用默认代理,该代理使用 Windows 身份验证。它将使用默认凭据,该凭据将在 Windows 设置中设置。然后它会使用用户提供的凭据在 Web 服务上执行基本身份验证。
更新
客户端尝试了此操作,但收到了 400 错误:
System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
当我在没有代理的机器上尝试时,它工作正常。知道为什么吗?
I have a web service that uses basic authentication. I also have a Windows Forms application that uses the web service. When it starts up, the user is asked for credentials, which are then used when making any requests to the service.
Problem is, the app is used by a client from within a corporate network. All their internet traffic is routed through a proxy that uses Windows authentication. I'm trying to configure my application to correctly use that proxy when making requests.
So far I have this in my client application's app.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="mySoap" closeTimeout="00:02:00" openTimeout="00:02:00"
receiveTimeout="00:10:00" sendTimeout="00:02:00" allowCookies="false"
bypassProxyOnLocal="true" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="Windows"
realm="myrealm" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.myservice.com/service.asmx"
binding="basicHttpBinding" bindingConfiguration="mySoap"
contract="MyPublicService.mySoap" name="mySoap" />
</client>
</system.serviceModel>
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
Do you think that's going to work? I can't easily test it. The app and service have been tested without the proxy and they work just fine, I just need to configure the proxy correctly.
Theoretically, this configuration would make sure that all requests use the default proxy, which uses Windows authentication. It would use the default credentials, which would be set up in their Windows settings. And then it would use the user-provided credentials to perform basic authentication on the web service.
UPDATE
The client tried this and got a 400 error back:
System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
It works fine when I try from my machine without the proxy. Any idea why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
400错误与该问题无关。 NTLM 代理的授权似乎适用于此配置。
更新:
我更改了服务器的安全配置以接受摘要。然后在设置用户名和密码时必须对代码进行一些小的更改,然后它就开始工作了。看起来绑定在基本身份验证方面存在问题。
The 400 error is not related to the issue. Authorisation with the NTLM proxy seems to be working with this config.
UPDATE:
I changed the server's security configuration to accept Digest as well. Then had to make small changes in the code when setting user name and password, and it started working. Looks like the binding had issues with Basic authentication.