• WCF消息拦截,利用消息拦截做身份验证服务


    本文参考  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"即为用户名和密码,你可以根据程序 的用户名和密码对基进行修改!!!

    到此,一个简单的消息拦截,身份验证就完成 了!

  • 相关阅读:
    AES算法,DES算法,RSA算法JAVA实现
    spring官方学习地址
    逐步理解SpringMVC
    sublime前端开发工具常用技巧
    谈谈关键字new
    关于mybatisgenerator的问题
    AOPjdk动态代理的思考
    关于java解析xml文件出现的问题
    Java注解
    git向码云上传代码总结
  • 原文地址:https://www.cnblogs.com/chcong/p/4323134.html
Copyright © 2020-2023  润新知