本文参考 http://blog.csdn.net/tcjiaan/article/details/8274493 博客而写
添加对信息处理的类
/// <summary> /// 消息拦截 /// </summary> public class MyMessageInspector:IClientMessageInspector,IDispatchMessageInspector { //用户名密码 static private string uName = "admin"; static private string pWord = "admin"; //初始化 public MyMessageInspector() { } public MyMessageInspector(string name, string pass) { uName = name; pWord = pass; } //客户端接收的信息之后的处理 void IClientMessageInspector.AfterReceiveReply(ref Message replaly, object correlationState) { Console.WriteLine("客户端接收的信息: {0}",replaly.ToString()); } //客户端发送消息之前的处理 object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel) { //Console.WriteLine("客户端发送请求前的SOAP消息: {0}", request.ToString()); MessageHeader hdUserName = MessageHeader.CreateHeader("u", "fuck", uName); MessageHeader hdPassWord = MessageHeader.CreateHeader("p", "fuck", pWord); request.Headers.Add(hdUserName); request.Headers.Add(hdPassWord); return null; } //服务 端接收到消息之后的处理 object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { //Console.WriteLine("服务器端:接收到的请求: {0}", request.ToString()); string un = request.Headers.GetHeader<string>("u", "fuck"); string ps = request.Headers.GetHeader<string>("p", "fuck"); if (un == "admin" && ps == "abcd") { Console.WriteLine("用户名和密码正确。"); } else { throw new Exception("验证失败,滚吧!"); } return null; } //服务端在发送消息之前的处理 void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState) { Console.WriteLine("服务器即将作出以下回复: {0}", reply.ToString()); } }
以上的用户名和密码都是固定值 ,你可以查询数据库,判断 是否有此用户,来保证 身份安全性
添加插入结结点的方法类
/// <summary> /// 插入到终结点的Behavior /// </summary> public class MyEndPointBehavior : IEndpointBehavior { //用户名密码 private string UserName = "admin"; private string PassWord = "admin"; public MyEndPointBehavior() { } public MyEndPointBehavior(string name,string pass) { UserName = name; PassWord = pass; } public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { return; } public void ApplyClientBehavior(ServiceEndpoint endopint ,ClientRuntime clientRuntime) { // 植入“偷听器”客户端 clientRuntime.MessageInspectors.Add(new MyMessageInspector(UserName,PassWord)); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { // 植入“偷听器” 服务器端 endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MyMessageInspector(UserName,PassWord)); } public void Validate(ServiceEndpoint endpoint) { return; } }
上面类的用户名和密码是由客户端传过来的,如果客户端没有传过来则默认都为 "admin"
注,以上两个类在服务 端和客户端都需要被引用
宿主程序 ,采用控制台应用程序
static void Main(string[] args) { Uri baseAddress = new Uri("http://localhost:1378/services"); using (ServiceHost host = new ServiceHost(typeof(WCF_LanJie_Lib.Service), baseAddress)) { WSHttpBinding bind = new WSHttpBinding(); host.AddServiceEndpoint(typeof(WCF_LanJie_Lib.IService),bind,"/Test"); // 添加服务描述 host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); // 把自定义的IEndPointBehavior插入到终结点中 foreach (var endpont in host.Description.Endpoints) { endpont.Behaviors.Add(new WCF_LanJie_Lib.MyEndPointBehavior()); } try { // 打开服务 host.Open(); Console.WriteLine("服务已启动。"); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); } }
其中,添加服务描述 HttpGetEnabled = true 是用于打开元数据 ,可供访问和下载
foreach ()循环是用来把服务 终结点和消息拦截的类相联系起来
客户端
客户端也是一个控件台应用程序
static void Main(string[] args) { Client.ServiceClient cli = new Client.ServiceClient();//引用 //定义一个消息拦截类,初始化 WCF_LanJie_Lib.MyEndPointBehavior mypoint = new MyEndPointBehavior("admin", "abcd"); // 把自定义的IEndPointBehavior插入到终结点中 cli.Endpoint.Behaviors.Add(mypoint); //服务端调用方法 Console.WriteLine(cli.GetDate("qwe")); Console.ReadLine(); }
其中 字符串 "admin"即为用户名和密码,你可以根据程序 的用户名和密码对基进行修改!!!
到此,一个简单的消息拦截,身份验证就完成 了!