从wcf客户端调用需要基本http身份验证的Web服务

时间:2010-08-16 18:03:04

标签: .net wcf web-services

我有一个来自Web服务的wsdl,我生成了wcf代理。没问题。

但我无法理解如何传递用户名和密码。 Web服务需要基本身份验证 - 只有用户名和密码。

任何帮助?

5 个答案:

答案 0 :(得分:24)

配置文件中是否配置了基本身份验证?您是否只需要传递凭据,还是需要安全传输(HTTPS)?

首先,您需要设置绑定以支持基本身份验证

HTTP绑定的设置:

<bindings>
  <basicHttpBinding>
    <binding name="BasicAuth">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

HTTPS绑定的设置:

<bindings>
  <basicHttpBinding>
    <binding name="BasicAuthSecured">
      <security mode="Transport">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

客户端端点必须使用如下定义的配置:

<client>
  <endpoint address="..." 
            name="..." 
            binding="basicHttpBinding" 
            bindingConfiguration="BasicAuth" 
            contract="..."  />
</client>

然后您必须将凭据传递给代理:

proxy = new MyServiceClient();
proxy.ClientCredentials.UserName.UserName = "...";
proxy.ClientCredentials.UserName.Password = "...";

答案 1 :(得分:1)

对于(A)在.NET Core项目的上下文中来回答这个问题的人,以及(B)对代码而不是XML文件中的更改感兴趣的人:

  1. 使用dotnet-svcutil使用WSDL来编写代码。
  2. 更新 Reference.cs 方法中的 GetBindingForEndpoint 以启用Basic Authentication in WCF client
  3. 使用客户端实例时设置登录名和密码。

示例代码:

private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
    if ((endpointConfiguration == EndpointConfiguration.YourService))
    {
        System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
        result.MaxBufferSize = int.MaxValue;
        result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
        result.MaxReceivedMessageSize = int.MaxValue;
        result.AllowCookies = true;

        // Set Basic Authentication with HTTP protocol (for HTTPS you need "Transport"):
        result.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
        result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

        return result;
    }
    throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}
var client = new YourServiceClient();
client.ClientCredentials.UserName.UserName = "yourservicelogin";
client.ClientCredentials.UserName.Password = "yourservicepassword";

答案 2 :(得分:0)

参考 @Gerard Jaryczewski.NET Core 项目中的回答,您也可以使用以下扩展方法,因为编辑 Reference.cs 可能是一个挑战,因为每次更新 Reference.cs 后,更改将被覆盖。

public static class BasicAuthenticationExtension
{
    public static void SetBasicAuthentication<T>(this ClientBase<T> client, string userName, string password) where T : class
    {
        if (client == null) throw new ArgumentNullException(nameof(client));
        if (client.Endpoint == null || client.Endpoint.Binding == null) throw new Exception("The specified client has no binding defined!");

        if (client.Endpoint.Binding is BasicHttpsBinding httpsBinding)
        {
            httpsBinding.Security.Mode = BasicHttpsSecurityMode.Transport;
            httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        }
        else if (client.Endpoint.Binding is BasicHttpBinding httpBinding)
        {
            httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        }
        else
        {
            throw new NotSupportedException("The specified client has a binding defined which is not supporting HTTP basic authentication!");
        }

        client.ClientCredentials.UserName.UserName = userName;
        client.ClientCredentials.UserName.Password = password;
    }
}

然后您可以像这样使用它:

var client = new MyServiceClient();
client.SetBasicAuthentication("myUserName", "myPassword");

答案 3 :(得分:-1)

这应该涵盖它:http://msdn.microsoft.com/en-us/library/ms733775.aspx (参见客户部分)

答案 4 :(得分:-1)

我想说这很可能取决于Web服务希望您传递信息的方式。 毕竟,你只是消费者。

话虽如此,Web服务通常是在SOAP Header中传递用户标识和密码。

您可以参考此link获取此方案的示例实现

示例肥皂消息

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <AUTHHEADER xmlns="http://tempuri.org/">
      <USERNAME>string</USERNAME>
      <PASSWORD>string</PASSWORD>
    </AUTHHEADER>
  </soap:Header>
  <soap:Body>
    <SENSITIVEDATA xmlns="http://tempuri.org/" />
  </soap:Body>
</soap:Envelope>