【问题标题】:How to programmatically turn off security in WCF如何以编程方式关闭 WCF 中的安全性
【发布时间】:2010-12-15 23:54:52
【问题描述】:

过去两天我一直在使用 WCF,它在我的开发机器上的服务器和客户端都运行良好。现在我正在尝试在网络上的另一台机器上对客户端进行一些分布式测试,我开始遇到问题。现在我得到的错误是:

由于 EndpointDispatcher 的 ContractFilter 不匹配,接收方无法处理带有 Action 'http://tempuri.org/IWindowUpdateContract/UpdateWindowFrames' 的消息。这可能是因为合约不匹配(发送方和接收方之间的操作不匹配)或发送方和接收方之间的绑定/安全不匹配。检查发送方和接收方是否具有相同的合同和相同的绑定(包括安全要求,例如消息、传输、无)。

由于这已经是一次大规模的学习体验(我之前没有做过任何远程处理、RPC 等)我想继续开发学习工具并在完成后重新审视安全性(我无意构建任何东西)这实际上会在没有适当的安全最佳实践的情况下被使用)。

注意事项:

  • 我没有为 WCF 设置配置文件 - 我正在以编程方式进行所有操作。
  • 我的网络不是域的一部分,因此默认安全设置对我不起作用(使用 net.tcp)。
  • 我正在使用“.Net 3.5”。

我的服务器是这样创建的:

    var svh = new ServiceHost(_serviceImplementation);

    var binding = new NetTcpBinding();

    binding.ReaderQuotas.MaxArrayLength = 2000000;
    binding.Security.Mode = SecurityMode.None;
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None;

    svh.AddServiceEndpoint(_serviceInterface, binding, string.Format("net.tcp://{0}:{1}", _endPoint.Address, _endPoint.Port));

    _stopFlag = new AutoResetEvent(false);

    svh.Open();

    _stopFlag.WaitOne();

我的客户端是这样创建的:

    var binding = new NetTcpBinding();

    binding.ReaderQuotas.MaxArrayLength = 2000000;
    binding.Security.Mode = SecurityMode.None;
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None;

    var scf = new ChannelFactory<IUserInputContract>(binding, "net.tcp://192.168.0.42:8001");
    _uiUpdateServer = scf.CreateChannel();

我的合同(只是在一个类库中,作为对客户端和服务器的引用添加)是:

    [ServiceContract(ProtectionLevel = ProtectionLevel.None)]
    public interface IWindowUpdateContract {
        [OperationContract]
        void UpdateWindowFrames(WindowFrame frame);
        [OperationContract]
        void WindowHasClosed(IntPtr hwnd);
}

我觉得我所做的绑定和合同设置应该使它们相同,我不应该有这个问题(并且应该关闭安全性)。我只是不知道现在该去哪里。

【问题讨论】:

    标签: wcf wcf-security


    【解决方案1】:

    我同意你的看法 - 服务器和客户端的安全设置似乎是相同的。

    附注:一旦你这样做:

    binding.Security.Mode = SecurityMode.None;
    

    我认为您不需要在“binding.Security”对象或以下指定任何更多设置 - 不需要之后的那些额外行。

    引起我注意的是你们的服务合同:

    [ServiceContract(ProtectionLevel = ProtectionLevel.None)]
    public interface IWindowUpdateContract 
    {
        [OperationContract]
        void UpdateWindowFrames(WindowFrame frame);
        [OperationContract]
        void WindowHasClosed(IntPtr hwnd);
    }
    

    这些操作不会返回任何内容 - 这很不寻常。 WCF 服务的默认行为是请求/响应 - 您发送请求并返回响应。

    要么让它们返回一些东西(一个状态等;比如一个字符串,一个 int),要么你需要将它们标记为“单向”调用,以便 WCF 知道不期望返回任何东西:

    [ServiceContract(ProtectionLevel = ProtectionLevel.None)]
    public interface IWindowUpdateContract 
    {
        [OperationContract(IsOneWay=true)]
        void UpdateWindowFrames(WindowFrame frame);
        [OperationContract(IsOneWay=true)]
        void WindowHasClosed(IntPtr hwnd);
    }
    

    马克

    【讨论】:

    • 我尝试添加“IsOneWay”属性,并将绑定代码减少到您提到的那一行,现在一切正常。非常感谢您的帮助!我觉得这两种情况中的任何一种都可能导致该特定错误有点奇怪......但我没有更改任何其他内容,现在它可以工作了!
    • @curiouscoder:我相信 IsOneWay=true 设置会有所不同。
    猜你喜欢
    • 2022-10-14
    • 2013-01-06
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 2011-07-15
    相关资源
    最近更新 更多