学会WCF之试错法——安全配置报错分析

服务端配置

<system.serviceModel>
     <bindings>
      <wsHttpBinding>
        <binding name ="WsHttpBinding_IService" maxReceivedMessageSize="370000" receiveTimeout="00:10:01" maxBufferPoolSize="100">
          <readerQuotas maxStringContentLength="240000"/>
          <security mode="Transport">
            <transport clientCredentialType="Windows"></transport>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="WCF_Find_Error_Lib.Service" behaviorConfiguration="beh">
        <endpoint address="" 
                  binding="wsHttpBinding"
                  contract="WCF_Find_Error_Lib.IService" 
                  bindingConfiguration="WsHttpBinding_IService">
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/S" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="beh">
          <serviceThrottling maxConcurrentCalls="1"/>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" httpGetUrl="http://localhost/S"/>
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

服务契约

[ServiceContract]
    public interface IService
    {
        [OperationContract]
        string GetData(int value);

        [OperationContract]
        string GetString(string value);

        [OperationContract]
        void Upload(Request request);
    }

    [MessageContract]
    public class Request
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName { get; set; }

        [MessageBodyMember(Order = 1)]
        public Stream Content {get;set;}
}

服务

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class Service : IService
    {
        public string GetData(int value)
        {
            //Thread.Sleep(120000);
            return string.Format("You entered: {0}", value);
        }

        public string GetString(string value)
        {
            //Thread.Sleep(120000);
            Thread.Sleep(5000);
            return string.Format("You entered: {0}", value);
        }

        public void Upload(Request request)
        {
            try
            {
                StreamReader sr = new StreamReader(request.Content, Encoding.GetEncoding("GB2312"));
                StreamWriter sw = new StreamWriter("E:\\" + request.FileName + ".txt", false, Encoding.GetEncoding("GB2312"));
                while (!sr.EndOfStream)
                {
                    sw.WriteLine(sr.ReadLine());
                    Thread.Sleep(5000);
                }
                sr.Close();
                sw.Close();
            }
            catch (Exception ex)
            { }
            
        }
  }

服务寄宿

  class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ServiceHost host = new ServiceHost(typeof(Service));
                host.Open();
                Console.WriteLine("服务状态:"+host.State.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            

            Console.WriteLine("服务启动");
            Console.WriteLine("按任意键停止服务");
            Console.ReadLine();
        }
  }

客户端配置

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name ="WsHttpBinding_IService" maxReceivedMessageSize="370000" receiveTimeout="00:10:01" maxBufferPoolSize="100">
          <readerQuotas maxStringContentLength="240000"/>
          <security mode="Transport">
            <transport clientCredentialType="Windows">
            </transport>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost/S" binding="wsHttpBinding"
          bindingConfiguration="WsHttpBinding_IService" contract="IService"
          name="WHttpBinding_IService" />
    </client>
  </system.serviceModel>

客户端代理

  public class ServiceProxy
    {
        public string GetData(int value)
        {
            string ret = null;
            ServiceClient client = null;
            try
            {
                client = new ServiceClient();
                ret = client.GetData(value);
                client.Close();
            }
            catch
            {
                if (client != null)
                {
                    client.Abort();
                }
                throw;
            }
            return ret;
        }

        public string GetString(string value)
        {
            string ret = null;
            ServiceClient client = null;
            try
            {
                client = new ServiceClient();
                ret = client.GetString(value);
                client.Close();
            }
            catch
            {
                if (client != null)
                {
                    client.Abort();
                }
                throw;
            }
            return ret;
        }
        public void Upload(Request request)
        {
            ServiceClient client = null;
            try
            {
                client = new ServiceClient();
                client.Upload(request);
                client.Close();
            }
            catch
            {
                if (client != null)
                {
                    client.Abort();
                }
                throw;
            }
        }

    }


    [ServiceContractAttribute(ConfigurationName = "IService")]
    public interface IService
    {

        [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/GetData", ReplyAction = "http://tempuri.org/IService/GetDataResponse")]
        string GetData(int value);

        [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/GetString", ReplyAction = "http://tempuri.org/IService/GetStringResponse")]
        string GetString(string value);

        [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/Upload", ReplyAction = "http://tempuri.org/IService/UploadResponse")]
        void Upload(Request request);
    }
    [MessageContract]
    public class Request
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName { get; set; }

        [MessageBodyMember(Order = 1)]
        public Stream Content { get; set; }
    }
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class ServiceClient : System.ServiceModel.ClientBase<IService>, IService
    {

        public ServiceClient()
        {
        }

        public string GetData(int value)
        {
            return base.Channel.GetData(value);
        }

        public string GetString(string value)
        {
            return base.Channel.GetString(value);
        }

        public void Upload(Request request) 
        {
            base.Channel.Upload(request);
        }
  }

1 Transport安全模式(本机调试)

客户端调用

using (ServiceClient client = new ServiceClient())
{
    StreamReader sr = new StreamReader("D:\\CSBMTEMP.txt", Encoding.Default);
    string str = sr.ReadToEnd();
    sr.Close();
    var s = client.GetString(str);
}

服务端和客户端配置如上。wsHttpBinding的Message安全模式,客户端凭据默认为Windows

运行客户端,抛出异常:

抛出异常的原因是,Transport模式支持HTTPS,TCP,ICP,MSMQ,而这里终结点地址是http://localhost/S,没有使用HTTPS协议。将终结点地址改为https://localhost/S即可。

服务端和客户端配置的安全模式不一样时

服务端安全模式修改为:

<security mode="Transport">
       <transport clientCredentialType="Basic"></transport>
</security>

客户端保持不变:

<security mode="Transport">
     <transport clientCredentialType="Windows"></transport>
</security>

运行客户端,抛出异常:

将客户端安全配置改为Basic,与服务端相同

<security mode="Transport">
            <transport clientCredentialType="Basic"></transport>
</security>

运行客户端,抛出异常,因为Transport模式不支持Basic这种客户端凭据。

2 Message安全模式(本机调试)

wsHttpBinding的Message安全模式,客户端凭据默认为Windows。

服务地址配置为https://localhost/S,服务端与客户端安全模式相同

<security mode="Message">
     <transport clientCredentialType="Windows"></transport>
</security>

运行客户端,抛出异常

抛出异常的原因是,wsHttpBinding的Message安全模式不支持https协议,改为http协议则正常。

但是,当服务端的客户端凭据配置与客户端不一致时,也可以正常执行,并获得正常的结果。

例如,服务端配置:

<security mode="Message">
       <transport clientCredentialType="Basic"></transport>
</security>

客户端配置:

<security mode="Message">
      <transport clientCredentialType="Windows"></transport>
</security>

-----------------------------------------------------------------------------------------

时间仓促,水平有限,如有不当之处,欢迎指正。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GuZhenYin

使用localResizeIMG3+WebAPI实现手机端图片上传

前言 惯例~惯例~昨天发表的使用OWIN作为WebAPI的宿主..嗯..有很多人问..是不是缺少了什么 - - 好吧,如果你要把OWIN寄宿在其他的地方...代...

2078
来自专栏大内老A

我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案

几个星期之前写了一篇关于如何通过WCF进行 双向通信的文章([原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communic...

1786
来自专栏.net core新时代

npoi批量导入实现及相关技巧

  批量导入功能对于大部分后台系统来说都是不可或缺的一部分,常见的场景-基础数据的录入(部门,用户),用批量导入方便快捷。最近项目需要用到批量导入,决定花点时间...

4335
来自专栏挖坑填坑

使用typescript开发angular模块(编写模块)

之前在使用typescript开发angular模块(发布npm包)一文中基本掌握了怎么发布一个typescript写的npm包。但是离目标还有段距离。

1123
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出

昨天文章太过仓促没有补充导出的示例源码,在者当时弄到到很晚没时间做出导出功能,对阅读理解造成影响,现补充一份示例源码,顺便补充导出的功能说明,望理解 示例代...

4657
来自专栏技术小讲堂

探寻ASP.NET MVC鲜为人知的奥秘(3):寻找多语言的最佳实践方式

如果你的网站需要被世界各地的人访问,访问者会使用各种不同的语言和文字书写习惯,那么创建一个支持多语言的网站就是十分必要的了,这一篇文章就讲述怎么快速合理的创建网...

2758
来自专栏恰同学骚年

自己动手写一个简单的MVC框架(第一版)

  路由(Route)、控制器(Controller)、行为(Action)、模型(Model)、视图(View)

1342
来自专栏技术之路

【权限的思考】(一)使用反射实现动态权限

  每一个业务系统都会根据业务需要配置各种各样的权限,实现方式也是千差万别,各有各的优缺点。今天我们 利用反射来做一个小的权限管理Demo。也可以说是插件化的权...

2009
来自专栏一只程序汪的自我修养

ASP.NET MVC 微信JS-SDK认证

2213
来自专栏大内老A

我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案

几个星期之前写了一篇关于如何通过WCF进行 双向通信的文章([原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communic...

2118

扫码关注云+社区