构建安全的Xml Web Service系列之如何察看SoapMessage

上一篇文章地址:构建安全的Xml Web Service系列一之初探使用Soap头 (5-22 12:53)    
     要分析Xml Web Service的安全性,首先要解决的问题是我们能了解和清楚Soap消息的格式和内容,如果获得不了SoapMessage,分析如何能构建安全Xml web service也就无从下手,即使分析出来,自己也可 能模模糊糊,不能定论。下面就分析下如何获得SoapMessage。
    首先介绍一个类-SoapExtension,msdn对这个类的备注为:ASP.NET 允许通过扩展性机制生成与 SOAP 相关的基础结构。ASP.NET SOAP 扩展结构以一种扩展为中心,该扩展可以在客户端或服务器上处理消息时在特定阶段中检查或修改消息。ASP.NET SOAP 扩展从 SoapExtension 类派生。GetInitializer 和 Initialize 方法提供其他可用机制,用于初始化 SOAP 扩展以增强性能。ProcessMessage 是大多数 SOAP 扩展的核心,原因是该方法在 SoapMessageStage 中定义的每一个阶段都被调用,从而使 SOAP 扩展得以执行所需的该特定 SOAP 扩展的行为。对于需要修改 SOAP 请求或 SOAP 响应的 SOAP 扩展,ChainStream 提供一个机会以接收要通过网络发送的建议数据。 仔细阅读这段文字,如果您以前开发过windows程序,那第一个应该想到的是:原来web service的处理机制和windows窗口程序的消息机制竟然有着一曲同工之妙。下面谈谈如何利用这个类,来截获Xml web Service请求和相应的Soap消息,从而看看xml web service的庐山真面目。
    首先大家先看看这个类,这个类完成的功能是将Xml Web Service通过扩展的方式,将每次的请求和响应的Soap消息通过日志的方式保存到文本文件中。日志记录的方式也有两种:
    1。针对每个WebMethod产生一个日志文件。
    2。针对每个WebService产生一个日志文件
 因为一个WebService可能包含一个或者多个WebMethod,所以如果指定两种方法都支持的话,那第二个日志两面应该包括第一个日志里面的内容,而有些情况下,是不需要对每个WebMethod都进行日志记录的,这时候采用第一种记录方式,增强了系统的灵活性。 
下面是扩展了的SoapExtension
None.gif <webServices>
None.gif        
<soapExtensionTypes>
None.gif          
<add type="Jillzhang.TraceExtension,Jillzhang" priority="1"  group="High"  />
None.gif        
</soapExtensionTypes>
None.gif      
</webServices>
ContractedBlock.gifExpandedBlockStart.gif可以记录SoapMessage的SoapExtension
None.gifnamespace Jillzhang
None.gif{
None.gif    public class TraceExtension: SoapExtension
None.gif    {
None.gif        static readonly string LogRoot = System.Configuration.ConfigurationManager.AppSettings["logRoot"];
None.gif        Stream oldStream;
None.gif        Stream newStream;
None.gif        string filename;
None.gif
None.gif       /// 
<summary>
None.gif       /// 将请求流和响应流存到内存流中,已被调用
None.gif       /// 
</summary>
None.gif        /// 
<param name="stream">包含 SOAP 请求或响应的内存缓冲区</param>
None.gif        /// 
<returns>它表示此 SOAP 扩展可以修改的新内存缓冲区。</returns>
None.gif        public override Stream ChainStream(Stream stream)
None.gif        {
None.gif            oldStream = stream;
None.gif            newStream = new MemoryStream();
None.gif            return newStream;
None.gif        }
None.gif
None.gif        /// 
<summary>
None.gif        /// 在Xml Web Service第一次运行的时候,一次性的将通过TraceExtensionAttribute传递进来的
None.gif        /// 保存日志信息的文件名初始化
None.gif        /// 
</summary>
None.gif        /// 
<param name="methodInfo">应用 SOAP 扩展的 XML Web services 方法的特定函数原型</param>
None.gif        /// 
<param name="attribute">应用于 XML Web services 方法的 SoapExtensionAttribute</param>
None.gif        /// 
<returns>SOAP 扩展将对其进行初始化以用于缓存</returns>
None.gif        public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
None.gif        {
None.gif            return ((TraceExtensionAttribute)attribute).Filename;
None.gif        }
None.gif
None.gif        /// 
<summary>
None.gif        /// 替代为每个方法配置的保存SoapMessage文件名,而是将整个网络服务
None.gif        /// 的SoapMessage都保存到一个日志文件中,这个文件路径需要在Web Service
None.gif        /// 的配置文件中web.config指出,如
None.gif        /// 
<appSettings>
None.gif        ///  
<add key="logRoot" value="c:\\serviceLog"/>
None.gif        /// 
</appSettings>
None.gif        /// 
</summary>
None.gif        /// 
<param name="WebServiceType">网络服务的类型</param>
None.gif        /// 
<returns>用于保存日志记录的文件路径</returns>
None.gif        public override object GetInitializer(Type WebServiceType)
None.gif        {
None.gif            //return LogRoot.TrimEnd('\\') + "\\" + WebServiceType.FullName + ".log";
None.gif            return LogRoot.TrimEnd('\\')+"\\"+ WebServiceType.FullName + ".log";
None.gif        }
None.gif
None.gif        //获得文件名,并将其保存下来
None.gif        public override void Initialize(object initializer)
None.gif        {
None.gif            filename = (string)initializer;
None.gif        }
None.gif
None.gif       /// 
<summary>
None.gif       /// 当数据还为Soap格式的时候,将数据写入日志
None.gif       /// 
</summary>
None.gif       /// 
<param name="message"></param>
None.gif        public override void ProcessMessage(SoapMessage message)
None.gif        {
None.gif            switch (message.Stage)
None.gif            {
None.gif                case SoapMessageStage.BeforeSerialize:
None.gif                    break;
None.gif                case SoapMessageStage.AfterSerialize:
None.gif                    WriteOutput(message);
None.gif                    break;
None.gif                case SoapMessageStage.BeforeDeserialize:
None.gif                    WriteInput(message);
None.gif                    break;
None.gif                case SoapMessageStage.AfterDeserialize:
None.gif                    break;
None.gif                default:
None.gif                    throw new Exception("invalid stage");
None.gif            }
None.gif        }
None.gif        /// 
<summary>
None.gif        /// 将SoapMessage写入到日志文件
None.gif        /// 
</summary>
None.gif        /// 
<param name="message"></param>
None.gif        public void WriteOutput(SoapMessage message)
None.gif        {
None.gif            newStream.Position = 0; 
None.gif            //创建或追加记录文件
None.gif            FileStream fs = new FileStream(filename, FileMode.Append,
None.gif                FileAccess.Write);
None.gif            StreamWriter w = new StreamWriter(fs);
None.gif            string soapString = (message is SoapServerMessage) ? "Soap响应" : "Soap请求";
None.gif            w.WriteLine("-----" + soapString + " 在 " + DateTime.Now.ToString("yyyy年MM月dd日 HH时mm分ss秒"));
None.gif            w.Flush();
None.gif            Copy(newStream, fs);
None.gif            w.Close();
None.gif            newStream.Position = 0;
None.gif            Copy(newStream, oldStream);
None.gif        }
None.gif
None.gif        public void WriteInput(SoapMessage message)
None.gif        {
None.gif            Copy(oldStream, newStream);
None.gif            FileStream fs = new FileStream(filename, FileMode.Append,
None.gif                FileAccess.Write);
None.gif            StreamWriter w = new StreamWriter(fs);
None.gif
None.gif            string soapString = (message is SoapServerMessage) ?
None.gif                 "Soap请求" : "Soap响应";
None.gif            w.WriteLine("-----" + soapString +
None.gif                " 在 " + DateTime.Now.ToString("yyyy年MM月dd日 HH时mm分ss秒"));
None.gif            w.Flush();
None.gif            newStream.Position = 0;
None.gif            Copy(newStream, fs);
None.gif            w.Close();
None.gif            newStream.Position = 0;
None.gif        }
None.gif        /// 
<summary>
None.gif        /// 拷贝流到流
None.gif        /// 
</summary>
None.gif        /// 
<param name="from"></param>
None.gif        /// 
<param name="to"></param>
None.gif        void Copy(Stream from, Stream to)
None.gif        {
None.gif            TextReader reader = new StreamReader(from);
None.gif            TextWriter writer = new StreamWriter(to);
None.gif            writer.WriteLine(reader.ReadToEnd());
None.gif            writer.Flush();
None.gif        }
None.gif    }
None.gif
None.gif    //创建一个用于在WebMethod上使用的SoapExtension属性
None.gif    [AttributeUsage(AttributeTargets.Method)]
None.gif    public class TraceExtensionAttribute : SoapExtensionAttribute
None.gif    {
None.gif
None.gif        private string filename = "c:\\log.txt";
None.gif        private int priority;
None.gif
None.gif        /// 
<summary>
None.gif        /// 扩展类型
None.gif        /// 
</summary>
None.gif        public override Type ExtensionType
None.gif        {
None.gif            get { return typeof(TraceExtension); }
None.gif        }
None.gif        /// 
<summary>
None.gif        /// 优先级 
None.gif        /// 
</summary>
None.gif        public override int Priority
None.gif        {
None.gif            get { return priority; }
None.gif            set { priority = value; }
None.gif        }
None.gif        /// 
<summary>
None.gif        /// 用于记录该WebMethod的SoapMessage的文件的绝对路径
None.gif        /// 默认为c:\\log.txt;
None.gif        /// 
</summary>
None.gif        public string Filename
None.gif        {
None.gif            get
None.gif            {
None.gif                return filename;
None.gif            }
None.gif            set
None.gif            {
None.gif                filename = value;
None.gif            }
None.gif        }
None.gif    }   
None.gif}
None.gif
结下来,介绍一个如何使用该类:
如果要使让TraceExtension支持第一种记录方式,需要作的额外工作为:
只需要在要记录SoapMessage的WebMethod添加如下的Attribute
[TraceExtension(Filename="d:\\data.xml",Priority=0)]
当然路径,您可以自己设定
前一节的WebMethod就变成了
ContractedBlock.gifExpandedBlockStart.gif添加了针对WebMethod日志记录的WebMethod
None.gif public MySoapHeader header = new MySoapHeader();        
None.gif        [WebMethod]
None.gif        [SoapHeader("header")]   
None.gif        [TraceExtension(Filename="d:\\data.xml",Priority=0)]
None.gif        public string HelloWorld()
None.gif        {
None.gif            if (header == null)
None.gif            {
None.gif                return "您没有设置SoapHeader,不能正常访问此服务!";
None.gif            }
None.gif            if (header.UserName != "jillzhang" || header.Pwd != "123456")
None.gif            {
None.gif                return "您提供的身份验证信息有误,不能正常访问此服务!";
None.gif            }
None.gif            return "Hello World";
None.gif        }
调用下该WebService,便在d盘产生一个data.xml文件,里面的内容为:
ContractedBlock.gifExpandedBlockStart.gif日志记录
None.gif-----Soap请求 在 2007年05月25日 09时06分29秒
None.gif
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header><MySoapHeader xmlns="http://tempuri.org/"><UserName>jillzhang</UserName><Pwd>123456</Pwd></MySoapHeader></soap:Header><soap:Body><HelloWorld xmlns="http://tempuri.org/" /></soap:Body></soap:Envelope>
None.gif
None.gif
None.gif-----Soap响应 在 2007年05月25日 09时06分29秒
None.gif
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><HelloWorldResponse xmlns="http://tempuri.org/"><HelloWorldResult>Hello World</HelloWorldResult></HelloWorldResponse></soap:Body></soap:Envelope>
None.gif
如何采用第二种方法,让WebService的每个WebMethod都能记录日志
需要在Web.config中作如下的设定
首先添加如下节点
None.gif <webServices>
None.gif        
<soapExtensionTypes>
None.gif          
<add type="Jillzhang.TraceExtension,Jillzhang" priority="1"  group="High"  />
None.gif        
</soapExtensionTypes>
None.gif      
</webServices>
然后通过配置设定日志文件保留的路径:
None.gif<appSettings>
None.gif    
<add key="logRoot" value="d:"/>
None.gif  
</appSettings>
找到日志文件,里面也赫然有着SoapMessage的真面目。通过以上方法,大家可以清晰地分析到SoapMessage的具体格式和内容,知道了这个以后,对付Web Service,您就可以随心应手,随心所欲,如果你愿意,你甚至也可以“强奸"一次webservice,哈哈!
上一篇文章地址:构建安全的Xml Web Service系列一之初探使用Soap头 (5-22 12:53)
附:终于买上房了,虽然买的过程很累,但现在还是很Happy!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276421.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端高效开发必备的 js 库梳理

之前有很多人问学好前端需要学习哪些 js 库, 主流框架应该学 vue 还是 react ? 针对这些问题, 笔者来说说自己的看法和学习总结.首先我觉得在学习任何知识之前必须要有一个明确的学习目标, 知道自己为什么要学它, 而不是看网上说的一股脑的给你灌输各种知识, 让你学习各种库, …

交叉报表crosstab隐藏列名显示_SAP软件 报表查询之 输出格式设置

SAP不仅是功能强大、逻辑严谨的ERP软件&#xff0c;还提供了强大的报表查询功能。SAP的ALV报表展示功能是SAP的一大特点&#xff0c;实现了类似于EXCEL的功能。使用好ALV报表功能可以方便用户从SAP中取到想要的数据&#xff0c;尤其是财务用户。大家在使用SAP报表时&#xff0c…

seo每日一贴_白杨SEO:我看ZAC的外贸SEO应该怎样做?(策略篇)

前言&#xff1a;这是白杨SEO公众号更新第64篇。本该写写头条SEO啥的&#xff0c;最近在师徒培训讲站内SEO时有旁听同学提到后面讲讲谷歌SEO怎么样&#xff0c;因为谷歌全世界搜索市场占有率&#xff0c;所以外贸SEO最主要还是做谷歌SEO。以白杨特意又去了前辈ZAC的SEO每日一贴…

[转]网页栅格系统研究(2):蛋糕的切法

[出自]http://lifesinger.org/blog/2008/10/grid-system-2/首先澄清一个应用场景问题。研究&#xff08;1&#xff09;中指出&#xff0c;对于结构复杂的网站&#xff0c;不少设计师们喜欢采用960固定宽度布局。但要注意的是&#xff0c;960并不是万能钥匙&#xff0c;大部分网…

Vue3响应式原理

关注若川视野&#xff0c;回复"pdf" 领取资料&#xff0c;回复"加群"&#xff0c;可加群长期交流学习本文结构- 关于Vue3- Vue2响应式原理回顾- Vue3响应式方案- Vue3响应式原理- 手写mini版Vue3响应式本文共计&#xff1a;2349字2图预计阅读时间&#xff…

找准切入点,调试看源码,事半功倍

关注若川视野&#xff0c;回复"pdf" 领取资料&#xff0c;回复"加群"&#xff0c;可加群长期交流学习最近写了很多源码分析相关的文章&#xff0c;React、Vue 都有&#xff0c;想把我阅读源码的一些心得分享给大家。React&#xff1a;React 架构的演变 - 从…

Android布局大全

Android的界面是有布局和组件协同完成的&#xff0c;布局好比是建筑里的框架&#xff0c;而组件则相当于建筑里的砖瓦。组件按照布局的要求依次排列&#xff0c;就组成了用户所看见的界面。 所有的布局方式都可以归类为ViewGroup的5个类别&#xff0c;即ViewGroup的5个直接子类…

java实现加减乘除运算符随机生成十道题并判断对错_2020年Java面试题(3年的工作总结),最全的知识点总结...

这份Java面试题整整花了三个月的时间来整理&#xff0c;都是自己再工作中总结出来&#xff0c;记住多少就写多少&#xff0c;希望这份资料可以帮助你们&#xff0c;文末有其余部分资料的领取方式.Redis12道面试题1.什么是Redis&#xff1f;答&#xff1a;Remote Dictionary Ser…

.NET 中的泛型 101

1.1.1 摘要 图1 C# 泛型介绍 在接触泛型之前&#xff0c;我们编程一般都是使用具体类型&#xff08;char, int, string等&#xff09;或自定义类型来定义我们变量&#xff0c;如果我们有一个功能很强的接口&#xff0c;而且我们想把它提取或重构成一个通用的接口&#xff0c;使…

年底了,给想进阶的的前端朋友一些福利

2020 年&#xff0c;很多朋友都经历了一段比较艰难的求职季。年末&#xff0c;“就业寒冬”迎来了一丝暖阳&#xff0c;很多中大型互联网公司扩大了未来一年的招聘需求。前不久&#xff0c;字节跳动放出了年末要招 1 万人的消息&#xff0c;腾讯校招规模也将扩张至 5000 人&…

Vue Router 4.0 正式发布!焕然一新。

关注若川视野&#xff0c;回复"pdf" 领取资料&#xff0c;回复"加群"&#xff0c;可加群长期交流学习12月8日&#xff0c;Vue Router 4 正式发布稳定版本。在经历了 14 个 Alpha&#xff0c;13 个 Beta 和 6 个 RC 版本之后&#xff0c;Vue Router v4 闪亮…

实战Nginx与PHP(FastCGI)的安装、配置与优化

转载链接&#xff1a;http://ixdba.blog.51cto.com/2895551/806622 一、什么是 FastCGI FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI&#xff0c;包括Apache、Nginx和lighttpd等&#xff0c;同时&#xff0c;…

10个前端8个用Vue的,怎么才能在面试中出彩?

大家好&#xff0c;我是若川。现在但凡出去面试&#xff0c;面试官几乎必问 Vue3.0 。不仅会问一些核心特性&#xff0c;还会问原理层面的问题。比如&#xff1a;▶框架层面问题&#xff1a;Vue3.0 新特性 Composition API 与 React.js 中 Hooks 的异同点&#xff1f;▶源码、原…

故乡 | 登高望远,夜幕降临

欢迎星标我的公众号若川视野&#xff0c;回复加群&#xff0c;长期交流学习上周末看了几集豆瓣评分8.5分刘同同名小说的青春剧《我在未来等你》&#xff0c;让我回想起自己的高中生活。也想起小时候经常爬到故乡附近的小山&#xff0c;看夕阳西下。时常和同事开玩笑说&#xff…

CentOS5安装Nginx1.4+PHP5.5 FastCGI

转载链接&#xff1a;http://blog.csdn.net/staricqxyz/article/details/17012329 yum -y install gcc gcc-c autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2…

一份热乎乎的滴滴前端面经

关注若川视野&#xff0c;回复"pdf" 领取资料&#xff0c;回复"加群"&#xff0c;可加群长期交流学习滴滴前端实习面经滴滴是我投简历之后第二家面试的公司&#xff0c; 国庆节前两三天投的简历&#xff0c; 国庆后复工第一天就给我打了电话约一面。那时候…

用webBrowser取源文件取不到的点击数--选秀榜selectop.com网站内容管理系统之六

用idhttp可以取到源文件&#xff0c;但网站用脚本代码&#xff0c;源文件是看不到&#xff0c;并且代码的结果也取不出。webBrowser可以多次返回下载到的内容&#xff0c;不包括任何html语法&#xff0c;这个当中就有文章的点击数。在WebBrowser1DownloadComplete事件中处理&am…

真诚推荐几个最值得关注的前端公众号

前端技术日新月异&#xff0c;发展迅速&#xff0c;作为一个与时俱进的前端工程师&#xff0c;需要不断的学习。这里强烈推荐几个前端开发工程师必备的优质公众号&#xff0c;希望对你有所帮助。大家可以像我一样&#xff0c;利用碎片时间阅读这些公众号的文章。code秘密花园一…

Silverlight Unit Test Framework

微软在08年的时候推出了一个Silverlight的单元测试框架&#xff0c;该框架在Mix 08的时候与Silverlight controls同时推出的&#xff0c;微软工程师Jeff Wilcox一直参与维护该单元测试框架。Scott Gu对这个框架的介绍Jeff Wilcox提供的视频介绍该框架的源代码已经包括在Silverl…

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

转载链接&#xff1a;http://freeloda.blog.51cto.com/2033581/1288553 大纲 一、前言 二、环境准备 三、安装与配置Nginx 四、Nginx之反向代理 五、Nginx之负载均衡 六、Nginx之页面缓存 七、Nginx之URL重写 八、Nginx之读写分离 注&#xff0c;操作系统为 CentOS 6.4 x86_64…