学会WCF之试错法——安全配置报错分析
Posted 甜橙很酸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学会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>
-----------------------------------------------------------------------------------------
转载与引用请注明出处。
时间仓促,水平有限,如有不当之处,欢迎指正。
以上是关于学会WCF之试错法——安全配置报错分析的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 报错 DioError [DioErrorType.DEFAULT]: Bad state: Insecure HTTP is not allowed by platform(代码片段