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

时间:2022-08-10 02:42:55

服务端配置

<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 = )]
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();
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();
}
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 = )]
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

运行客户端,抛出异常:

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

抛出异常的原因是,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>

运行客户端,抛出异常:

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

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

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

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

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

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

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

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

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

运行客户端,抛出异常

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

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

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

例如,服务端配置:

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

客户端配置:

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

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

转载与引用请注明出处。

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