实现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>
用对方法才有效率,做对事情才有效果
“麻烦”是自己“处理”不当的结果
“困难”是自己“学习”不够的反射
“挫折”是自己“努力”不足的代价
“麻烦”是自己“处理”不当的结果
“困难”是自己“学习”不够的反射
“挫折”是自己“努力”不足的代价