zoukankan      html  css  js  c++  java
  • webservice接口验证

    webservice接口使用方便,兼容性强,目前web服务很多采用这种方式

    开发webservice接口也很简单,本文主要涉及webservice中xml的验证。

    1.XSD数据验证

    目前交流行的是xsd数据格式验证

    一个简单的xsd文档

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema id="XSDEmrNotes"
       
        elementFormDefault="qualified"
       
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
         
    >
     <xs:element name="EmrNotes">
        <xs:complexType>
          <xs:sequence>
              <xs:element name="id" type="idT"/>
            <xs:element name="User" type="UserT"/>
            <xs:element name="pwd" type="pwdT"/>
            <xs:element name="Name" type="NameT"/>
         </xs:sequence>
        </xs:complexType>
      </xs:element>
    
      <xs:simpleType name="idT">
        <xs:restriction base="xs:int">
          <xs:pattern value="[0-9]{1,12}"/>
        </xs:restriction>
      </xs:simpleType>
      
      <xs:simpleType name="UserT">
        <xs:restriction base="xs:string">
          <xs:maxLength value="100"/>
          <xs:minLength value="1"/>
        </xs:restriction>
      </xs:simpleType>
    
    
      <xs:simpleType name="pwdT">
        <xs:restriction base="xs:int">
          <!--[0-9]{18}|[0-9]{17}X|[0-9]{17}x|[0-9]{17}|[0-9]{15}-->
          <xs:pattern value="[0-9]{1,18}"/>
        </xs:restriction>
      </xs:simpleType>
    
      <xs:simpleType name="NameT">
        <xs:restriction base="xs:string">
          <xs:maxLength value="100"/>
          <xs:minLength value="1"/>
        </xs:restriction>
      </xs:simpleType>
    pattern为限制条件,采用正则

    对应的xml文档为

    <?xml version="1.0" encoding="utf-8" ?>
    <EmrNotes >
      <id>123</id>                     
      <User>用户名</User>                 
      <pwd>1234567891</pwd>
    <Name>姓名</Name>
    </EmrNotes>

    这里需要注意的是如果要命名空间的话,xml与xsd的命名空间需要一致,但是命名空间容易在以后的序列化中出现问题,所以全不要命名空间

    二者之间需要匹配验证,为此写了一个验证类,这时构造函数:

            /// <summary>
            /// 构造验证类
            /// </summary>
            /// <param name="xmlString">xml实体</param>
            /// <param name="Sheet">表名</param>
            public  ValidationWebModel(string xmlString, string Sheet)
            {
                dataSheet = Sheet;
                XmlSchemaSet schemaSet = new XmlSchemaSet();
                schemaSet.Add(null, System.Web.HttpContext.Current.Server.MapPath("~/XXX/xml/XXX/" + dataSheet + "/" + dataSheet + ".xsd"));
    
               
                settings.ValidationEventHandler += new ValidationEventHandler(this.ValidationEventHandler);
                settings.ValidationType = ValidationType.Schema;
                settings.Schemas = schemaSet;
    
                xmlByte = Encoding.UTF8.GetBytes(xmlString);
    
                dataSheet = Sheet;
    
            }

    验证的话使用xmlReader流过一遍,就像这样 while (xmlRead.Read()){}.早期也有人使用XmlSchemaCollection与XmlValidatingReader的方式来验证,也可以,但是目前MSDN上此方法已过时,所以不采用。

    当然我们还需要一个ValidationEventHandler方法供XmlSchemaSet 作为过滤方法,所以定义如下

       /// <summary>
            /// 验证传入的xml文档是否符合规范
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ValidationEventHandler(Object sender, ValidationEventArgs e)
            {
                if (e.Severity == XmlSeverityType.Warning)
                {
                    // errorMassage = "插入成功." + e.Message;
                    dataMessage = e.Message;
                }
                else if (e.Severity == XmlSeverityType.Error)
                {
                    errorMassage = "插入失败," + e.Message;
                }
    
            }

    整个类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    using TeleStrokes;
    using UsersInfo;
    
    namespace TeleStrokesWeb.webService
    {
        public class ValidationWebModel
        {
            //业务操作类
            EmrNotesBLL emrNotesBll=new EmrNotesBLL();
            UsersBLL usersBll = new UsersBLL();
            //EmrAcceBLL emrAcceBll;
            //xml设置规则
            XmlReaderSettings settings = new XmlReaderSettings();
            //数据表名
            string dataSheet;
    
            //传入的字节
            byte[] xmlByte;
            /// <summary>
            /// 要返回的错误信息
            /// </summary>
            public  string errorMassage
            { get; set; }
    
            /// <summary>
            /// 数据详情
            /// </summary>
            public string dataMessage
            { get; set; }
    
            /// <summary>
            /// 构造验证类
            /// </summary>
            /// <param name="xmlString">xml实体</param>
            /// <param name="Sheet">表名</param>
            public  ValidationWebModel(string xmlString, string Sheet)
            {
                dataSheet = Sheet;
                XmlSchemaSet schemaSet = new XmlSchemaSet();
                schemaSet.Add(null, System.Web.HttpContext.Current.Server.MapPath("~/Dictionary/xml/TeleStrokes/" + dataSheet + "/" + dataSheet + ".xsd"));
    
               
                settings.ValidationEventHandler += new ValidationEventHandler(this.ValidationEventHandler);
                settings.ValidationType = ValidationType.Schema;
                settings.Schemas = schemaSet;
    
                xmlByte = Encoding.UTF8.GetBytes(xmlString);
    
                dataSheet = Sheet;
    
            }
    
          /// <summary>
            ///  开始验证方法
          /// </summary>
          /// <param name="dataSheet">要使用的数据表</param>
          /// <returns></returns>
            public  T Check<T>()where T:class
            {
                using (MemoryStream ms = new MemoryStream(xmlByte))
                {
                    using (XmlReader xmlRead = XmlReader.Create(ms, settings))
                    {
                        while (xmlRead.Read())
                        {
    
                        }
                        if (string.IsNullOrEmpty(errorMassage))
                        {
                            ms.Position = 0;
    
                            //验证成功,符合规范
                            ms.Position = 0;
                            if (dataSheet == "EmrAcce")
                            {
                                //验证附件表
                                T result = SeralizeModel<T>(ms,CheckEmrNotesRealtion );
                                return result;
                            }
                            else if (dataSheet == "EmrNotes") 
                            {
                                //验证病历表
                                Func<object, bool> notesValidate = CheckUserRelation;
                                notesValidate += ValidateIp;
                                notesValidate += CheckAddUser;
    
                                T result = SeralizeModel<T>(ms, notesValidate);
                                return result;
                            }
                            else
                            {
                                errorMassage = "传错表了";
                                return null;
                            }
                         //  return  SeralizeModel(ms, dataSheet);
                           
                        }
                        else
                        {
                            return default(T);
                        }
                    }
                }
            }
    
            /// <summary>
            /// 序列化并且验证表实体
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="reader"></param>
            /// <param name="validate"></param>
            /// <returns></returns>
            private T SeralizeModel<T>(Stream reader,Func<object,bool> validate)where T:class
            {
                T newModel = XmlSerializer<T>(reader);
    
                validate(newModel);
    
                return newModel;
    
            }
    
            /// <summary>
            /// 序列化传入的流对象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="stream"></param>
            /// <returns></returns>
            private T XmlSerializer<T>(Stream stream)where T:class
            {
                XmlSerializer ser = new XmlSerializer(typeof(T));
                T tModel = ser.Deserialize(stream) as T ;
                return tModel;
            }
     
    
            /// <summary>
            /// 如果存在病人用户名验证是否在用户表中,返回警告信息
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="newEmrNote"></param>
            /// <returns></returns>
            private bool CheckUserRelation(object newEmrNote)
            {
                EmrNotes newEmrNotes = (EmrNotes)newEmrNote;
               
                if (!string.IsNullOrEmpty(newEmrNotes.EnUser))
                {
                    if (usersBll.GetUsersCheck(newEmrNotes.EnUser)) { return true;}
                    else
                    {
                        dataMessage = "病人用户不是系统注册用户";
                        return false;
                    }
    
                }
                return false;
            }
    
            /// <summary>
            /// 检查录入员是否是系统用户
            /// </summary>
            /// <param name="newEmrNote"></param>
            /// <returns></returns>
            private bool CheckAddUser(object newEmrNote)
            {
                EmrNotes newEmrNotes = (EmrNotes)newEmrNote;
                if (!string.IsNullOrEmpty(newEmrNotes.EnAddUser))
                {
                    if (usersBll.GetUsersCheck(newEmrNotes.EnAddUser)) { return true; }
                    else
                    {
                        dataMessage = "录入员不是系统注册用户";
                        return false;
                    }
    
                }
                return false;
            }
    
    
           /// <summary>
            /// 检查传入的附件有无病历表中的相关项
           /// </summary>
           /// <typeparam name="T"></typeparam>
           /// <param name="newEmrAcce"></param>
           /// <returns></returns>
            private bool CheckEmrNotesRealtion(object newEmrAcce)
            {
                EmrAcce newModel = (EmrAcce)newEmrAcce;
                //验证是否是之前的数据关联
                EmrNotes result = emrNotesBll.GetEmrNotes(newModel.Enid);
                if (result == null)
                {
                    errorMassage = "没有相关病历的记录,请先传入病历表";
                    return false;
                }
                else
                {
    
                    return true;
                }
            }
    
    
            /// <summary>
            /// 验证传入的xml文档是否符合规范
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ValidationEventHandler(Object sender, ValidationEventArgs e)
            {
                if (e.Severity == XmlSeverityType.Warning)
                {
                    // errorMassage = "插入成功." + e.Message;
                    dataMessage = e.Message;
                }
                else if (e.Severity == XmlSeverityType.Error)
                {
                    errorMassage = "插入失败," + e.Message;
                }
    
            }
    
            /// <summary>
            /// 根据ip验证是否是用户本人
            /// </summary>
            /// <param name="userName"></param>
            /// <returns></returns>
            private bool ValidateIp(object AcceNotes)
            {
                string userName=((EmrNotes)AcceNotes).EnAddUser;
                if (string.IsNullOrEmpty(userName)) return true;
                Users currentUser = usersBll.GetUsers(userName);
                if (currentUser!=null)
                {
                    if (!string.IsNullOrEmpty(currentUser.URegIp))
                    {
                        if (currentUser.URegIp != GetIp())
                        {
                            //此处列为警告信息
                          //  errorMassage = "录入员用户的ip地址不对";
                            dataMessage = "录入员用户的ip地址不对";
                            return false;
                        }
                    }
                   
                }
    
                return true;
            }
    
            /// <summary>
            /// 获得iP地址
            /// </summary>
            /// <returns></returns>
            private string GetIp()
            {
              
                string ip = "";
    
                if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)// 服务器变量, using proxy
                {
                    ip = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
                }
                if (ip == "" || ip == null)//如果没有使用代理服务器或者得不到客户端的ip  
                {                            //得到服务端的地址    
    
                    ip = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString(); //While it can't get the Client IP, it will return proxy IP.
    
    
                    if (ip == "" || ip == null)//如果没有使用代理服务器或者得不到客户端的ip  not using proxy or cant get the Client IP
                    {
                        string strHostName = System.Net.Dns.GetHostName();
    
                        string clientIPAddress = System.Net.Dns.GetHostAddresses(strHostName).GetValue(0).ToString();
                    }
    
                    if (ip == "" || ip == null)
                    {
                        ip = HttpContext.Current.Request.UserHostAddress;
                    }
    
                }
                return ip;
            }    
        }
    }
    View Code

    2.soapHeader验证

    首先声明一个soapHeader的子类

        public class SoapHeaderValidate:System.Web.Services.Protocols.SoapHeader
        {
            /// <summary>
            /// 用户名
            /// </summary>
            public string UserName
            { get; set; }
            /// <summary>
            /// 密码
            /// </summary>
            public string UserPwd
            { get; set; }
            /// <summary>
            /// 构造函数1
            /// </summary>
            public SoapHeaderValidate()
             {
                
             }
            /// <summary>
            /// 构造函数2
            /// </summary>
            /// <param name="UserName"></param>
            /// <param name="UserPwd"></param>
            public SoapHeaderValidate(string userName, string userPwd)
            {
                UserName = userName;
                UserPwd = userPwd;
            }
    }

    然后在类中写一些验证方法

      /// <summary>
            /// 主调方法:用于验证是否调用接口的用户存在
            /// </summary>
            /// <param name="ErroMsg"></param>
            /// <returns></returns>
            public  bool IsValid(out string ErroMsg)
            {
                ErroMsg = "";
                try
                {
                    if (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(UserPwd)) 
                    {
                        ErroMsg = "没有传递用户名";
                        return false;
                    }
    
                    UsersBLL userBll = new UsersBLL();
                    //暂定为测试有无用户名,以后改为状态或者登陆验证
                    if (!userBll.GetUsersCheck(UserName)) 
                    {
                        ErroMsg = "用户名错误";
                        return false;
                    }
                    return true;
                }
                catch (Exception)
                {
                    
                    throw;
                }
            }

    然后回到接口处在接口大类中声明了这个soapHeader后,添加如下标签

      [SoapHeader("myHeader")]
            [WebMethod(Description = "测试soap连接方法,返回ok")]
            public string Hello()
            {
                string msg = string.Empty;
                if (myHeader.IsValid(out msg)) return msg;
                return "Ok";
            }

    接口写上

         string msg = string.Empty;
                if (!myHeader.IsValid(out msg))
                {
                    return msg;
                }

    ok,别人发送的信息就必须得通过头部验证了

    客户端使用方式

      SendData.SoapHeaderValidate myHeader = new SendData.SoapHeaderValidate();
                myHeader.UserName = "bingren1";//
                myHeader.UserPwd = "111";

    把这个声明的头加到web方法的首个参数就可以了

  • 相关阅读:
    Python 爬虫js加密破解(一) 爬取今日头条as cp 算法 解密
    Python 爬虫实例(2)—— 爬取今日头条
    Python 爬虫实例(1)—— 爬取百度图片
    python 操作redis之——HyperLogLog (八)
    python 操作redis之——有序集合(sorted set) (七)
    Python操作redis系列之 列表(list) (五)
    Python操作redis系列以 哈希(Hash)命令详解(四)
    Python操作redis字符串(String)详解 (三)
    How to Install MySQL on CentOS 7
    Linux SSH远程文件/目录 传输
  • 原文地址:https://www.cnblogs.com/wanglao/p/3673831.html
Copyright © 2011-2022 走看看