过滤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 < * * )
{
stream.Position = ;
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 = ;
}
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("", ,by,true)); Console.ReadKey();
}
}
}

6.web.config配置

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

实现webservice过滤器,请求日志和权限等的更多相关文章

  1. cxf client在后台不通且chunk设置为false的时候不能在控制台输出请求日志

    场景: 服务编排框架支持编排webservice服务.call webservice的client是基于cxf做的.为了使用服务编排的开发者调试与定位问题方便,需要将webservice的请求与响应报 ...

  2. Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级

    1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...

  3. spring boot aop 自定义注解 实现 日志检验 权限过滤

    核心代码: package com.tran.demo.aspect; import java.lang.reflect.Method; import java.time.LocalDateTime; ...

  4. 46. Spring Boot中使用AOP统一处理Web请求日志

    在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...

  5. 异常详细信息: System.Security.SecurityException: 未找到源,不过,未能搜索部分或所有事件日志。 若要创建源,您需要用于读取所有事件日志的权限以确保新的源名称是唯一的。 不可访问的日志: Security。

    “/”应用程序中的服务器错误. 安全性异常 说明: 应用程序尝试执行安全策略不允许的操作.要授予此应用程序所需的权限,请与系统管理员联系,或在配置文件中更改该应用程序的信任级别. 异常详细信息: Sy ...

  6. 如何从Serilog请求日志记录中排除健康检查终结点

    这是在ASP.NET Core 3.X中使用Serilog.AspNetCore系列文章的第四篇文章:. 第1部分-使用Serilog RequestLogging减少日志详细程度 第2部分-使用Se ...

  7. 用SignalR实现实时查看WebAPI请求日志

    实现的原理比较直接,定义一个MessageHandler记录WebAPI的请求记录,然后将这些请求日志推送到客户端,客户端就是一个查看日志的页面,实时将请求日志展示在页面中. 这个例子的目的是演示如何 ...

  8. 其他信息: 未找到源,不过,未能搜索部分或所有事件日志。 若要创建源,您需要用于读取所有事件日志的权限以确保新的源名称是唯一的。 不可访问的日志: Security。

    其他信息: 未找到源,不过,未能搜索部分或所有事件日志.  若要创建源,您需要用于读取所有事件日志的权限以确保新的源名称是唯一的.  不可访问的日志: Security. System.Diagnos ...

  9. nginx记录响应与POST请求日志

    生产环境中的某些api出现故障,但是问题无法重现,但是又很想解决掉问题以及我们新项目上线,需要跟踪请求与响应的信息,可以预先找到一些bug,减少大面积的损失. 安装nginx与ngx_lua 响应日志 ...

随机推荐

  1. 【转】Java中的新生代、老年代、永久代和各种GC

    JVM中的堆,一般分为三大部分:新生代.老年代.永久代: 1 新生代 主要是用来存放新生的对象.一般占据堆的1/3空间.由于频繁创建对象,所以新生代会频繁触发MinorGC进行垃圾回收. 新生代又分为 ...

  2. 003 爬虫持久化的三个不同数据库的python代码

    MongoDB import pymongo # 1.连接MongoDB服务 mongo_py = pymongo.MongoClient() print(mongo_py) # 2.库和表的名字:有 ...

  3. jmeter和jdk的安装教程

    jmeter和jdk的安装教程 1:先下载安装jdk并且配置环境变量,配置环境变量的步骤如下: 右击计算机图标--点击属性--点击高级系统设置--点击环境变量后添加jdk的环境变量 a.系统变量→新建 ...

  4. 记录一个使用HttpClient过程中的一个bug

    最近用HttpClient进行链接请求,开了多线程之后发现经常有线程hang住,查看线程dump java.lang.Thread.State: RUNNABLE at java.net.Socket ...

  5. 防盗链之URL参数签名

    一.概述 传统的 IP 禁用.referer 防盗链.User-Agent 防盗链.地区访问控制等防盗链措施已经无法完全满足用户要求,所以开发出URL参数签名方式来防盗链 二.实现 Token防盗链是 ...

  6. 51nod1229 序列求和 V2

    这题...毒瘤吧,可能要写两份代码... 传送门 noteskey 我们考虑这里的复杂度肯定是与 k 相关的,而且平方也是没问题的,那么我们先看看 S(k) 能怎么得到: \[\begin{align ...

  7. computed计算属性

    在computed中,可以定义一些属性,这些属性 叫做计算属性.计算属性的本质是一个方法,只不过我们在使用的时候,把他们的名称当做属性来使用,并不会吧计算属性当做方法去调用.与methods平级. / ...

  8. deepin(debian)下使用Git

    Github github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开. 安装git 安装 sudo apt-get install g ...

  9. 【java】字节码操作技术

    asm.javassist.cglib. 1.asm 比较底层,使用的visitor设计模式. 官网:https://asm.ow2.io/ 2.javassist 官网:http://www.jav ...

  10. C# 高级编程03----细节内容

    一.名称空间 1.C#使用Using关键字可以列出所需类的名称控件. 它和C/C++ 中的#include不一样.using语句并没有在这些文件之间建立物理连接 2.使用using给名称空间指定别名 ...