Rex*_*gan 15 wcf web-services wcf-security .net-3.5
我已经获得了一个用Java编写的Web服务,我无法对其进行任何更改.它要求用户通过基本身份验证进行身份验证才能访问任何方法.在.NET中与此服务交互的建议方法是使用安装了WSE 3.0的Visual Studio 2005.
这是一个问题,因为该项目已经在使用Visual Studio 2008(面向.NET 2.0).我可以在VS2005中做到这一点,但我不想将项目与VS2005联系起来,或者通过在VS2005中创建一个程序集来实现它,并将其包含在VS2008解决方案中(无论如何,该程序基本上将项目绑定到2005,以便将来对程序集进行任何更改).我认为这些选项中的任何一个都会通过强制他们安装WSE 3.0并使项目无法在将来使用2008和.NET 3.5中的功能而使新开发人员变得复杂......即,我真的相信使用WCF是要走的路.
我一直在考虑使用WCF,但是我不确定如何让WCF服务理解它需要发送身份验证标头以及每个请求.当我尝试使用Web服务执行任何操作时,我收到401错误.
这就是我的代码:
WebHttpBinding webBinding = new WebHttpBinding();
ChannelFactory<MyService> factory =
new ChannelFactory<MyService>(webBinding, new EndpointAddress("http://127.0.0.1:80/Service/Service/"));
factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
factory.Credentials.UserName.UserName = "username";
factory.Credentials.UserName.Password = "password";
MyService proxy = factory.CreateChannel();
proxy.postSubmission(_postSubmission);
Run Code Online (Sandbox Code Playgroud)
这将运行并抛出以下异常:
HTTP请求未经授权,客户端身份验证方案为"匿名".从服务器收到的身份验证标头是"Basic realm = realm".
这有一个内在的例外:
远程服务器返回错误:(401)未经授权.
任何关于可能导致这个问题的想法将不胜感激.
mar*_*c_s 27
第一个问题:这是您尝试调用的SOAP或基于REST的Java服务吗?
现在,使用"webHttpBinding",您将使用基于REST的方法.如果Java服务是SOAP服务,那么您需要将绑定更改为"basicHttpBinding".
如果它是基于SOAP的服务,您应该尝试这样做:
BasicHttpBinding binding = new BasicHttpBinding();
binding.SendTimeout = TimeSpan.FromSeconds(25);
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
EndpointAddress address = new EndpointAddress(your-url-here);
ChannelFactory<MyService> factory =
new ChannelFactory<MyService>(binding, address);
MyService proxy = factory.CreateChannel();
proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "password";
Run Code Online (Sandbox Code Playgroud)
我已经将它用于各种Web服务,并且它可以工作 - 大部分时间.
如果这不起作用,您将不得不更多地了解Java Web服务所期望的内容以及如何将相关信息发送给它.
渣
首先在app.config或web.config中添加以下内容.(在环境中移动时无需更改):
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IConfigService">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:55283/ConfigService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IConfigService"
contract="IConfigService" name="BasicHttpBinding_IService" />
</client>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)
相应地将contract属性更改为Namespace.Interface名称.请注意安全模式= TransportCredentialOnly
现在,以编程方式更改端点并传递凭据,使用以下代码:
var myBinding = new BasicHttpBinding("BasicHttpBinding_IConfigService");
var myEndpoint = new EndpointAddress("http://yourbaseurl/configservice.svc");
var myChannelFactory = new ChannelFactory<IConfigService>(myBinding, myEndpoint);
var credentialBehaviour = myChannelFactory.Endpoint.Behaviors.Find<ClientCredentials>();
credentialBehaviour.UserName.UserName = @"username";
credentialBehaviour.UserName.Password = @"password";
IConfigService client = null;
try
{
client = myChannelFactory.CreateChannel();
var brands = client.YourServiceFunctionName();
((ICommunicationObject)client).Close();
}
catch (Exception ex)
{
if (client != null)
{
((ICommunicationObject)client).Abort();
}
}
Run Code Online (Sandbox Code Playgroud)