勇哥注:
此系列文章是梳理一下勇哥认为项目有用的WCF的知识点,读者须有WCF的开发经验。
wcf的安全机制
分为消息级与线路级
1。所有的wcf服务,不要使用证书(SSL证书,用于传输上的加密),证书很贵划不来
证书一个域名4K。
如果是 IOS下的webapi,是必须要证书的。
2。非证书使用方式
如果你的wcf需要对外,那么增加验证是必须的。
(1)如果对方是C#程序,可以在client和service端在header中增加参数再使用消息拦截,
【head] 中加用户名与密码
这样两边不需要额外代码

(图1)
如上图所示,我们在第一个Endpoint中置入用户名密码,在第二个endpoint取得用户名密码,如果不对,则拒绝访问。
java程序,使用用户名和密码,获取token,以后每个接口中都传输一个token参数进去。

(图2)
(2)如果对方是非C#程序,可以使用一个登陆接口,获取token参数后,client在以后每个调用中都需要传递token参数。
演示程序:
演示图1。

MyEndpointBehavior
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
namespace Lib
{
public class MyEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
throw new NotImplementedException();
}
/// <summary>
/// 这个是client实现的
/// </summary>
/// <param name="endpoint"></param>
/// <param name="clientRuntime"></param>
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new MyClientMessageInspector());
}
/// <summary>
/// 这个是service端实现的
/// </summary>
/// <param name="endpoint"></param>
/// <param name="endpointDispatcher"></param>
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MyDispatchMessageInspector());
}
public void Validate(ServiceEndpoint endpoint)
{
throw new NotImplementedException();
}
}
}MyClientMessageInspector.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
namespace Lib
{
public class MyClientMessageInspector : IClientMessageInspector
{
/// <summary>
/// 发送之后
/// </summary>
/// <param name="reply"></param>
/// <param name="correlationState"></param>
public void AfterReceiveReply(ref Message reply, object correlationState)
{
throw new NotImplementedException();
}
/// <summary>
/// 发送之前
/// </summary>
/// <param name="request"></param>
/// <param name="channel"></param>
/// <returns></returns>
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var username = "samsun";
var password = "123";
request.Headers.Add(MessageHeader.CreateHeader("username", "", username));
request.Headers.Add(MessageHeader.CreateHeader("password", "", password));
return request;
}
}
}MyDispatchMessageInspector.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
namespace Lib
{
public class MyDispatchMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
//request.Headers.Add(MessageHeader.CreateHeader("username", "", username));
//request.Headers.Add(MessageHeader.CreateHeader("password", "", password));
var username= request.Headers.GetHeader<string>("username","");
var password = request.Headers.GetHeader<string>("password", "");
if (username == "samsun" && password == "123")
{
return request;
}
throw new Exception("用户名或者密码错误");
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
throw new NotImplementedException();
}
}
}Client
using Contracts;
using Lib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace Client
{
class Program
{
static void Main(string[] args)
{
//using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice"))
//{
// //省略代码
// ICalculator proxy = channelFactory.CreateChannel();
// using (proxy as IDisposable)
// {
// proxy.DoWorker("hello world");
// Console.ReadKey();
// }
//}
ServiceReference1.CalculatorServiceClient client = new Client.ServiceReference1.CalculatorServiceClient();
client.Endpoint.EndpointBehaviors.Add(new MyEndpointBehavior());
try
{
client.DoWorker("Hello world");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
}
}host:
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace Hosting
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
host.Description.Endpoints[0].EndpointBehaviors.Add(new MyEndpointBehavior());
host.Opened += delegate
{
Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
};
host.Open();
Console.Read();
}
}
}wcf的负载均横
www.cnblogs.com/huangxincheng/p/7707830.html


少有人走的路


















