实现webservice过滤器,请求日志和权限等

 

过滤webservice的请求日志,做权限验证功能等。

1.

namespace WebApplication1
{
    public class SimpleWSInvokeMonitorExtension : SoapExtension
    {
        Stopwatch stopWatch = null;
        string startLoginfo = "";

        public override Stream ChainStream(Stream stream)
        {
            return stream;
        }
        public override object GetInitializer(Type serviceType)
        {
            //throw new NotImplementedException();
            return null;
        }

        public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
        {
            //throw new NotImplementedException();
            return null;
        }

        public override void Initialize(object initializer)
        {
            //throw new NotImplementedException();
        }

        public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
                    stopWatch.Stop();
                    var sec = stopWatch.ElapsedMilliseconds;
                    string endLogInfo = string.Format("{0},总花费时间{1}ms,请求ip{2}",
                        startLoginfo,
                        stopWatch.ElapsedMilliseconds.ToString(),
                        GetClientIp());

                    break;
                case SoapMessageStage.BeforeDeserialize:
                    break;
                //about to call method;
                case SoapMessageStage.AfterDeserialize:
                    CertficateSoap(message);
                    string soapMessage = string.Empty;
                    var stream = message.Stream;
                    // Just making sure again that we have got a stream which we 
                    // can read from AND after reading reset its position 
                    //------------------------------------------------------------
                    if (stream.CanRead && stream.CanSeek && stream.Length < 10 * 1024 * 1024)
                    {
                        stream.Position = 0;
                        StreamReader rdr = new StreamReader(stream);
                        soapMessage = rdr.ReadToEnd();

                        // IMPORTANT!! - Set the position back to zero on the original 
                        // stream so that HTTP pipeline can now process it
                        //------------------------------------------------------------
                        stream.Position = 0;
                    }
                    startLoginfo = GetStartLogInfo(soapMessage, message.MethodInfo.Name);
                    //采集时间
                    stopWatch = new Stopwatch();
                    stopWatch.Start();
                    break;
            }

        }
        /// <summary>
        /// 权限验证
        /// </summary>
        /// <param name="message"></param>
        public void CertficateSoap(SoapMessage message)
        {
            if (message.MethodInfo.CustomAttributeProvider.IsDefined(typeof(AllAnonymous), false))
                return;

            bool check = false;
            foreach (SoapHeader header in message.Headers)
            {
                if (header is CertficateSoapHeader)
                {
                    CertficateSoapHeader myHeader = (CertficateSoapHeader)header;

                    if (myHeader.UserName == null || myHeader.PassWord == null)
                    {
                        break;
                    }

                    if (myHeader.UserName.Equals("LY") && myHeader.PassWord.Equals("LY"))
                    {
                        check = true;
                        break;
                    }
                }
            }

            if (!check)
            {
                throw new SoapHeaderException(string.Format("认证失败{0}", message.MethodInfo.Name), SoapException.ClientFaultCode);
            }
        }
        public string GetStartLogInfo(string soapMessage, string methodName)
        {
            XDocument doc = XDocument.Parse(soapMessage);
            var body = doc.Descendants().Where(p => p.Name.LocalName == methodName).First();
            StringBuilder sb = new StringBuilder();
            foreach (XElement el in body.Nodes())
            {
                sb.Append(string.Format("{0}:{1},", el.Name.LocalName, el.Value));
            }
            string strLog = string.Format("外部系统请求方法:开始时间{0},方法{1},参数{2}", DateTime.Now.ToString(), methodName, sb.ToString());
            return strLog;
        }
        private static string GetClientIp(string ip = null)
        {
            if (String.IsNullOrEmpty(ip))
            {
                ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            }
            if (String.IsNullOrEmpty(ip) || ip.Equals("unknown", StringComparison.OrdinalIgnoreCase))
            {
                ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            if (ip == "::1")
                ip = "127.0.0.1";
            return ip;
        }
    }
}

2.在服务端的公开方法增加特性

 /// <summary>
    /// BotWebService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    //[ExtensionAttribute]
    [ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
    // [System.Web.Script.Services.ScriptService]

    public class BotWebService : System.Web.Services.WebService
    {
        public CertficateSoapHeader soapHeader; 
        [WebMethod(Description = "")]
        [SoapHeader("soapHeader", Direction = SoapHeaderDirection.In)]
        //[AllAnonymous] 有特性表示不需要验证权限,没就需要
        public string GetString(string name,int age,byte[] remark,bool isfalg)
        {
            return name + age;
        }
}

3.

    /// <summary>
    /// 该特性表示该方法不需要验证调用者的信息
    /// </summary>
    [AttributeUsage(AttributeTargets.Method,AllowMultiple = true,Inherited = false)]
    public class AllAnonymous:Attribute
    {

    }

4.

namespace WebApplication1
{
    /// <summary>
    /// 用于webservice认证
    /// </summary>
    public class CertficateSoapHeader : SoapHeader
    {
        /// <summary>
        /// 属性
        /// </summary>
        public string UserName { get; set; }
        public string PassWord { get; set; }


        
        public CertficateSoapHeader() { }
        /// <summary>
        /// 构造函数认证
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="passWord">密码</param>
        public CertficateSoapHeader(string userName, string passWord) 
        {
            this.UserName = userName;
            this.PassWord = passWord;
        }
    }
}

5.client

class Program
    {
        static void Main(string[] args)
        {
            localhost.BotWebService s = new localhost.BotWebService();
            localhost.CertficateSoapHeader header = new localhost.CertficateSoapHeader();
            header.UserName = "LY";
            header.PassWord = "LY";

            s.CertficateSoapHeaderValue = header;
            var by = Encoding.UTF8.GetBytes("你好啊,ewqeqwewq");
            //Console.WriteLine(s.HelloWorld());

           Console.WriteLine(s.GetString("111", 1,by,true));

            Console.ReadKey();
        }
    }
}

 6.web.config配置

 <system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="WebApplication1.SimpleWSInvokeMonitorExtension,WebApplication1" priority="1"/>
      </soapExtensionTypes>
    </webServices>
 </system.web>

 

posted @ 2017-05-15 14:43  英雄饶命啊  阅读(1934)  评论(0编辑  收藏  举报