Wcf基本身份验证不接受用户名

时间:2016-09-28 19:04:30

标签: c# wcf authentication wcf-binding

我正在尝试使用SOAP服务并遇到身份验证问题,并认为我可能会遗漏一些有用的东西。我认为问题可能在于我传递的标题不仅仅是凭据(我认为这是我必须做的事情,但认为它只是使情况更加独特)。下面是我的配置文件和我用来验证的代码。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="MemberSoap">
          <security mode="Transport" />
        </binding>
        <binding name="MemberSoap1" />
        <binding name="TransactionSoap">
          <security mode="Transport" />
        </binding>
        <binding name="TransactionSoap1" />
        <binding name="CertificateSoap" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
          <readerQuotas maxDepth="32" maxArrayLength="2147483647" maxStringContentLength="2147483647"/>
          <security mode="Transport" />
        </binding>
        <binding name="CertificateSoap1" />
        <binding name="MembershipSoap">
          <security mode="Transport">
            <transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>
        <binding name="ContentSoap">
          <security mode="Transport" />
        </binding>
        <binding name="ContentSoap1" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://membership/member.asmx"
        binding="basicHttpBinding" bindingConfiguration="MemberSoap"
        contract="Member.MembershipWsMemberSoap" name="Ovs.Membership.Ws.MemberSoap" />
      <endpoint address="https://membership/transaction.asmx"
        binding="basicHttpBinding" bindingConfiguration="TransactionSoap"
        contract="MembershipWsTransactionSoap" name="TransactionSoap" />
      <endpoint address="https://membership/certificate.asmx"
        binding="basicHttpBinding" bindingConfiguration="CertificateSoap"
        contract="MembershipWsCertificateSoap" name="CertificateSoap" />
      <endpoint address="https://ngmembership/Membership.svc"
        binding="basicHttpBinding" bindingConfiguration="MembershipSoap"
        contract="Membership.IMembership" name="MembershipSoap" />
      <endpoint address="https://membership/content.asmx"
        binding="basicHttpBinding" bindingConfiguration="ContentSoap"
        contract="Content.MembershipWsContentSoap" name="ContentSoap" />
    </client>
  </system.serviceModel>
    <appSettings>
      <add key="UsernameAuth" value="user" />
      <add key="PasswordAuth" value="pass" />
    </appSettings>
</configuration>

为了安全起见,我省略了基本网址以及完整的命名空间,但我主要关心的是name =“MembershipSoap”服务。这是我第一次尝试使用的代码进行身份验证。

public Transaction[] GetAllBookingInfo(string memberId, string partnerId)
{
    AllBookingsByMemberIdRS response;
    using (var client = new MembershipClient())
    using (new OperationContextScope(client.InnerChannel))
    {
        // add the basic auth header
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name]
            = GetBasicAuthHeader("user", "pass");
        var request = new AllBookingsByMemberIdRQ
        {
            MemberId = memberId,
            PartnerId = partnerId
        };
        response = AuthenticateServiceUser.membershipSession.GetAllBookingsByMemberId(request);
    }
    var trans = response.Transactions;
    return trans;
}

protected HttpRequestMessageProperty GetBasicAuthHeader(string userName, string password)
{
    // get the basic auth header
    HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
    httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + password));
    return httpRequestProperty;
}

此时我收到一条错误消息,指出“使用了无效的Web服务凭据”。所以在阅读之后我将第一种方法改为此。

public Transaction[] GetAllBookingInfo(string memberId, string partnerId)
{
    AllBookingsByMemberIdRS response;

    var client = new MembershipClient();
    client.ClientCredentials.UserName.UserName = "user";
    client.ClientCredentials.UserName.Password = "pass";

    using (new OperationContextScope(client.InnerChannel))
    {
        var request = new AllBookingsByMemberIdRQ
        {
            MemberId = memberId,
            PartnerId = partnerId
        };
        response = AuthenticateServiceUser.membershipSession.GetAllBookingsByMemberId(request);
    }
    var trans = response.Transactions;
    return trans;
}

现在我收到了'用户名未提供。在ClientCredentials的错误中指定用户名。所以现在我觉得我要走得更远了。也许有人可以对此有所了解?提前谢谢!

1 个答案:

答案 0 :(得分:0)

我明白了。我愚蠢地在我的代码中引用了另一个客户端 - 一个没有凭据。这些简单的错误总是被忽视。

public Transaction[] GetAllBookingInfo(string memberId, string partnerId)
{
    AllBookingsByMemberIdRS response;
    using (var client = new MembershipClient())
    using (new OperationContextScope(client.InnerChannel))
    {
        // add the basic auth header
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name]
            = GetBasicAuthHeader("user", "pass");
        var request = new AllBookingsByMemberIdRQ
        {
            MemberId = memberId,
            PartnerId = partnerId
        };
        response = client.GetAllBookingsByMemberId(request);
    }
    return response.Transactions;
}