c# - 具有 ClientCredentials 属性的 CreateChannel

标签 c# wcf client-certificates contract

我是 WCF 的新手,正在尝试使用自定义用户名和密码创建 WCF 服务。我知道我应该将用户名和密码设置为代理的 ClientCredentials,但出于某种原因,我没有这样的属性...

我认为它与我的契约(Contract)有关,所以这里是:

我的合约代码:

namespace Contracts
{    
    [ServiceContract]
    public interface ICalc
    {
        [OperationContract]
        CalcResponse Add(double x, double y);

        [OperationContract]
        CalcResponse Substract(double x, double y);

        [OperationContract]
        CalcResponse Multiply(double x, double y);

        [OperationContract]
        CalcResponse Divide(double x, double y);
    }
}

在我的客户中,我尝试做的是:

ChannelFactory<ICalc> channel = new ChannelFactory<ICalc>("calcEndpoint");
ICalc proxy = channel.CreateChannel();

proxy.ClientCredentials.UserName.UserName = "USER";
proxy.ClientCredentials.UserName.Password = "PASSWORD";

但是我的代理没有 ClientCredentials 属性

更新: 我遇到了一些导致其他错误的问题。当我解决它们时,我遇到了一个新错误:

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue.

我的超时时间在客户端和服务器端都设置为 5 分钟。我在不到一分钟后收到此错误...

这是我更新后的代码:

ChannelFactory<ICalc> channel = new ChannelFactory<ICalc>("calcEndpoint");

var defaultCredentials = channel.Endpoint.Behaviors.Find<ClientCredentials>();
channel.Endpoint.Behaviors.Remove(defaultCredentials);

ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = "Comply";
loginCredentials.UserName.Password = "123456";

channel.Endpoint.Behaviors.Add(loginCredentials); 
ICalc proxy = channel.CreateChannel();

我有一个自定义验证器,我在那里设置了一个断点,但它并没有成功... 我的验证器代码:

class CustomUserNameValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if (userName == "comply" && password == "123456")
        {
        }
    }
}

配置(在客户端和服务器上):

<service name ="WcfServiceLibrary.Service1" behaviorConfiguration ="CustomValidator">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/CalcIISHost/mex"/>
        <add baseAddress ="net.tcp://localhost:808/CalcIISHost/CalcService"/>
      </baseAddresses>
    </host>
    <endpoint address ="" binding ="netTcpBinding" bindingConfiguration="tcpWithMessageSecurity" contract ="Contracts.ICalc"></endpoint>
    <endpoint address ="net.tcp://localhost:5001/CalcIISHost/mex" binding ="mexTcpBinding" contract ="IMetadataExchange"></endpoint>
  </service>
...
<behavior name="CustomValidator">
      <serviceCredentials>
        <userNameAuthentication
          userNamePasswordValidationMode="Custom"
          customUserNamePasswordValidatorType="WCFClasses.CustomUserNameValidator, WCFClasses"/>
        <serviceCertificate
          findValue="localhost"
          x509FindType="FindBySubjectName"
          storeLocation="CurrentUser"
          storeName="My" />
      </serviceCredentials>
      <serviceMetadata httpGetEnabled ="true"/>
    </behavior>
...
<netTcpBinding>
    <binding name="tcpWithMessageSecurity"  sendTimeout="00:05:00" receiveTimeout="00:05:00">
      <security mode="Message" >
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </netTcpBinding>

知道我做错了什么吗?

最佳答案

您可以像这样设置凭据...

删除默认端点行为

ChannelFactory<ICalc> channel = new ChannelFactory<ICalc>("calcEndpoint");
var defaultCredentials = channel.Endpoint.Behaviors.Find<ClientCredentials>();
channel.Endpoint.Behaviors.Remove(defaultCredentials); 

创建凭据

ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = "USER";
loginCredentials.UserName.Password = "PASSWORD";

将凭据设置为工厂的新端点行为

channel.Endpoint.Behaviors.Add(loginCredentials); 
ICalc proxy = channel.CreateChannel();

编辑 2 月 27 日

我建议向您的服务添加日志记录,并在您的 Error.svclog 文件中发布您遇到的异常,在您的服务 app.config 中的配置标签下添加以下内容。

<system.diagnostics>
        <sources>
            <source name="System.ServiceModel"
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true" >
                <listeners>
                    <add name="xml"/>
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging">
                <listeners>
                    <add name="xml"/>
                </listeners>
            </source>
            <source name="myUserTraceSource"
                    switchValue="Information, ActivityTracing">
                <listeners>
                    <add name="xml"/>
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add name="xml"
                 type="System.Diagnostics.XmlWriterTraceListener"
                 initializeData="Error.svclog" />
        </sharedListeners>
    </system.diagnostics>

关于c# - 具有 ClientCredentials 属性的 CreateChannel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21878795/

相关文章:

c# - 使用序列化维护对象关系映射

wcf - 如何使 WCF 命名管道地址等于 WinApi 管道地址?

html - 如何在网络浏览器中自动安装客户端证书?

c# - 具有客户端证书和基本身份验证的 WCF 客户端

c# - 团结 : player moves up without any such code

c# - 如何将嵌入图像的相对路径分配给 ActiveSheet.PageSetup.LeftHeaderPicture.FileName?

c# - WCF 服务 - 编码标准 - 将我的类库放在哪里?

带有客户端证书的 Android 2.2 SSL Bug?

c# - WebClient.DownloadFile 究竟需要什么 URI?

java - 从 unity Activity 返回到 android studio 中的 MainActivity