`
javatoyou
  • 浏览: 1013680 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Soap协议扩展的应用及实现

阅读更多

Soap协议扩展的应用及实现




Soap协议 (简单对象传输)是一种基于 XML 的、用于在 Web 上交换结构化和类型信息的简单的轻量协议。SOAP 的总体设计目标是使其尽可能地简单,并提供最少的功能。该协议定义一个不包含任何应用程序或传输语义的消息处理框架。因此,该协议是模块化的,并具有很强的扩展性。
Soap 协议规范包含四个主要组成部分。第一部分定义用于封装数据的必需的可扩展信封。该 SOAP 信封定义 SOAP 消息,并且是 SOAP 消息处理器之间的基本交换单位。这是该规范唯一必需的部分。
SOAP 协议规范的第二部分定义用来表示应用程序定义的数据类型和有向图形的可选数据编码规则,以及用于序列化非句法数据模型的统一模型。
第三部分定义 RPC 样式(请求/响应)的消息交换模式。每个 SOAP 消息都是单向传输。尽管 SOAP 的根位于 RPC 中,但它不仅仅只是请求/响应机制。XML Web services 经常组合 SOAP 消息以实现此类模式,但 SOAP 并不强制要求消息交换模式,这部分规范也是可选的。
规范的第四部分定义 SOAP 和 HTTP 之间的绑定。但该部分也是可选的。可以将 SOAP 与任何能够传输 SOAP 信封的传输协议或机制(包括 SMTP FTP 甚至软盘)结合在一起使用。
Microsoft公司实现了soap协议,并使之成为.Net Framework的一个重要的基础.Microsoft.net的任何基于client-server的传输都是以soap的形式的.(httpGet 及httpPost 协议只是client应用).
举一个.Net的例子.如一个web service程序是 data.asmx:
<%@ WebService Language="C#" Class="data" %>
using System;
using System.Web.Services;
public class Order
{
public int OrderID;
public double Price;
}
public class data {
[WebMethod]
public Order GetOrder()
{
Order myOrder = new Order();
myOrder.Price=34.5;
myOrder.OrderID = 323232;
return myOrder;
}
}
现再用wsdl工具将web serivce的wsdl转换成client的代理程序,如:wsdl /protocol:Soap /namespace:D http://localhost/data1.asmx
(假设data1.asmx是放在iis服务器的根目录下(c:\inetpub\wwwroot)).
产生一个客户端的代理程序data.cs:
namespace D {
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="dataSoap", Namespace="http://tempuri.org/")]
public class data : System.Web.Services.Protocols.SoapHttpClientProtocol {
/// <remarks/>
public data() {
this.Url = "http://localhost/data1.asmx";
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/GetOrder", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public Order GetOrder() {
object[] results = this.Invoke("GetOrder", new object[0]);
return ((Order)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginGetOrder(System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("GetOrder", new object[0], callback, asyncState);
}
/// <remarks/>
public Order EndGetOrder(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((Order)(results[0]));
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public class Order {
/// <remarks/>
public int OrderID;
/// <remarks/>
public System.Double Price;
}
}
然后再将之编译成dll.如:csc /t:library /out:c:\inetpub\wwwroot\bin\data.dll data.cs.完成以后就可以使用.Net的client程序进行调用(如winform ,cs or aspx).
下面是用test.aspx实现client的调用的.
<%@ Import Namespace="D" %>
<html>
<style>
div
{
font: 8pt verdana;
background-color:cccccc;
border-color:black;
border-width:1;
border-style:solid;
padding:10,10,10,10;
}
</style>
<script language="C#" runat="server">
public void Page_Load(Object sender, EventArgs E)
{
data datatype =new data();
Order or=datatype.GetOrder();
Response.Write("order -==="+or.OrderID+"<br>");
}
</script>
</body>
</html>
运行这个程序,将在浏览器打印"order=======323232".
我们来研究client 同server到底传输了什么.
当我们执行test.aspx时,它调用到了data.cs的GetOrder()方法,然后序列化信息,并包装成:
<?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><GetOrder xmlns="http://tempuri.org/" /></soap:Body></soap:Envelope>
传输到server上,server接受信息以后,反序列化,然后调用server上的GetOrder()方法,得到一个返回值并序列化,得到一个流:
<?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><GetOrderResponse xmlns ="http://tempuri.org/"><GetOrderResult><OrderID>323232</OrderID><Price>34.5
</Price></GetOrderResult></GetOrderResponse></soap:Body></soap:Envelope>传输到client端.client端收到信息后再反序列得到值.
从上分析可知,soap协议就是一个传输数据的作用.但网络的传输是复杂的且有许多的不定因素,怎样去考虑安全性呢?client怎样确定server发的是可靠的信息而server又怎样辨认client呢?
Microsoft推出了Soap extension(扩展),来实现soap消息的加密与解密.
从下图可以看出soap扩展的用途:

正如您看到的,ASP.NET 在 XML Web services 计算机和 XML Web services 客户端计算机上的阶段中对 XML 进行序列化和反序列化。可以将 SOAP 扩展插入基础结构以在每个序列化和反序列化阶段的之前和之后检查或修改 SOAP 消息。例如,加密 SOAP 扩展可能在 ASP.NET 序列化客户端的参数之后加密 SOAP 消息的 XML 部分,而后在 ASP.NET 反序列化 SOAP 消息之前在 Web 服务器上解密 SOAP 消息。这些阶段(SOAP 扩展可能在这些阶段中检查或修改 SOAP 消息)是在 SoapMessageStage 枚举中定义的。在这种情况下,在 AfterSerialize 阶段加密 SOAP 扩展,在 BeforeDeserialize 阶段解密 SOAP 扩展。
通常,当 SOAP 扩展修改 SOAP 消息的内容时,必须在客户端和服务器上都进行修改。也就是说,如果要在客户端上运行 SOAP 扩展并加密 SOAP 消息,则相应的 SOAP 扩展必须在服务器上对该 SOAP 消息进行解密。如果未解密该 SOAP 消息,则 ASP.NET 基础结构不能将 SOAP 消息反序列化为对象。当然,不修改 SOAP 消息的 SOAP 扩展(例如仅记录 SOAP 消息的 SOAP 扩展)可以只在客户端或服务器上运行。在这种情况下,接收方接收与在 SOAP 扩展不运行并且 ASP.NET 基础结构可以反序列化 SOAP 消息的情况下相同的 SOAP 消息。另外,如果 SOAP 扩展不以一种使反序列化不能实现的方式对 SOAP 进行修改,则 SOAP 扩展不需要既运行在客户端又运行在服务器上。
调用 SOAP 扩展方法的顺序
我们看看在整个 XML Web services 方法调用过程中 ASP.NET 何时调用 SOAP 扩展方法。下面的步骤假设 SOAP 扩展既运行于客户端又运行于服务器上。如果 SOAP 扩展不同时运行于客户端和服务器上,则 ASP.NET 将忽略与 SOAP 扩展运行于其中任何一个相关联的步骤。
客户端
1. 客户端对代理类调用方法。
2. 在客户端上创建 SOAP 扩展的新实例。
3. 如果这是第一次在客户端上用该 XML Web services 执行该 SOAP 扩展,则对运行于客户端上的 SOAP 扩展调用 GetInitializer 方法。
4. 调用 Initialize 方法。
5. 调用 ChainStream 方法。
6. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 BeforeSerialize。
7. 客户端计算机上的 ASP.NET 将 XML Web services 方法的参数序列化为 XML。
8. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 AfterSerialize。
9. 客户端计算机上的 ASP.NET 通过网络将 SOAP 消息发送到承载该 XML Web services 的 Web 服务器。
服务器端
1. Web 服务器上的 ASP.NET 接收该 SOAP 消息。
2. 在 Web 服务器上创建 SOAP 扩展的新实例。
3. 在 Web 服务器上,如果这是第一次在服务器端使用该 XML Web services 执行该 SOAP 扩展,则对运行于服务器上的 SOAP 扩展调用 GetInitializer 方法。
4. 调用 Initialize 方法。
5. 调用 ChainStream 方法。
6. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 BeforeDeserialize。
7. ASP.NET 反序列化 XML 中的参数。
8. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 AfterDeserialize。
9. ASP.NET 创建实现 XML Web services 的类的新实例并调用 XML Web services 方法,同时传入反序列化的参数。该对象驻留在与 Web 服务器相同的计算机上。
10. XML Web services 方法执行其代码,最终会设置返回值和任何输出参数。
11. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 BeforeSerialize。
12. Web 服务器上的 ASP.NET 将返回值和输出参数序列化为 XML。
13. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 AfterSerialize。
14. ASP.NET 通过网络将 SOAP 响应消息发送回 XML Web services 客户端。
客户端
1. 客户端计算机上的 ASP.NET 接收 SOAP 消息。
2. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 BeforeDeserialize。
3. ASP.NET 将 XML 反序列化为返回值和任何输出参数。
4. 调用 ProcessMessage 方法,调用时将 SoapMessageStage 设置为 AfterDeserialize。
5. ASP.NET 将返回值和任何输出参数传递到代理类的实例。
6. 客户端接收返回值和任何输出参数。
我们现在以.Net的一个例子说明soap扩展的应用.
首先,我们写一个soap extension的程序,它是继承SoapExtension而来.
( TraceExtension.cs)
using System;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using System.Net;
// Define a SOAP Extension that traces the SOAP request and SOAP
// response for the XML Web service method the SOAP extension is
// applied to.
public class TraceExtension : SoapExtension
{
Stream oldStream;
Stream newStream;
string filename;
// Save the Stream representing the SOAP request or SOAP response into
// a local memory buffer.
public override Stream ChainStream( Stream stream ){
oldStream = stream;
newStream = new MemoryStream();
return newStream;
}
// When the SOAP extension is accessed for the first time, the XML Web
// service method it is applied to is accessed to store the file
// name passed in, using the corresponding SoapExtensionAttribute.
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
Stream fs = new FileStream("d:\\temp\\a.txt", FileMode.Create);
StreamWriter writer=new StreamWriter(fs);
writer.WriteLine("extension is ok ");
//writer.Flush();
//fs.Close();
writer.Close();
return ((TraceExtensionAttribute) attribute).Filename;
}
// The SOAP extension was configured to run using a configuration file
// instead of an attribute applied to a specific XML Web service
// method.
public override object GetInitializer(Type WebServiceType)
{
// Return a file name to log the trace information to, based on the
// type.
return WebServiceType.GetType().ToString() + ".log";
}
// Receive the file name stored by GetInitializer and store it in a
// member variable for this specific instance.
public override void Initialize(object initializer)
{
Stream fs = new FileStream("d:\\temp\\b.txt", FileMode.Create);
StreamWriter writer=new StreamWriter(fs);
writer.WriteLine("extension bb is ok ");
//writer.Flush();
//fs.Close();
filename = (string) initializer; //监控文件是:c:\winnt\system32\system.runtimetype.log
writer.WriteLine("filename ========="+filename);
writer.Close();
}
// If the SoapMessageStage is such that the SoapRequest or
// SoapResponse is still in the SOAP format to be sent or received,
// save it out to a file.
public override void ProcessMessage(SoapMessage message) //处理传输的数据.
{
switch (message.Stage) {
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
WriteOutput(message);
break;
case SoapMessageStage.BeforeDeserialize:
WriteInput(message);
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
}
public void WriteOutput(SoapMessage message){// 可以添加解密算法
newStream.Position = 0;
FileStream fs = new FileStream(filename, FileMode.Append,
FileAccess.Write);
StreamWriter w = new StreamWriter(fs);
string soapString = (message is SoapServerMessage) ? "SoapResponse" : "SoapRequest";
w.WriteLine("-----out ----" + soapString + " at " + DateTime.Now);
w.WriteLine("message ====="+message.MethodInfo.Name);
w.Flush();
Copy(newStream, fs);
w.Close();
newStream.Position = 0;
Copy(newStream, oldStream);
}
public void WriteInput(SoapMessage message){//可以添加加密算法
Copy(oldStream, newStream);
FileStream fs = new FileStream(filename, FileMode.Append,
FileAccess.Write);
StreamWriter w = new StreamWriter(fs);
string soapString = (message is SoapServerMessage) ?
"SoapRequest" : "SoapResponse";
w.WriteLine("-----int -------" + soapString +
" at " + DateTime.Now);
w.Flush();
newStream.Position = 0;
Copy(newStream, fs);
w.Close();
newStream.Position = 0;
}
void Copy(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.WriteLine(reader.ReadToEnd());
writer.Flush();
}
}
// Create a SoapExtensionAttribute for the SOAP Extension that can be
// applied to an XML Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute {
private string filename = "c:\\log.txt";
private int priority;
public override Type ExtensionType {
get { return typeof(TraceExtension); }
}
public override int Priority {
get { return priority; }
set { priority = value; }
}
public string Filename {
get {
return filename;
}
set {
filename = value;
}
}
}
我们将它编译成dll文件,如:csc /t:library /out:c:\inetpub\wwwroot\bin\TraceExtension.dll TraceExtension.cs
然后我们再写一个配置文件: web.config:
<configuration>
<system.web>
<webServices>
<soapExtensionTypes>
<add type="TraceExtension,TraceExtension" priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
将web.config存入c:\inetpub\wwwroot目录.
最后我们再运行test.aspx,我们可以在c:\winnt\system32\system.runtimetype.log文件中找到client与server端所传输的数据.我们可以在TraceExtension.cs 中的ProcessMessage(SoapMessage)方法中加上加密及解密算法,改变client-server传输的数据.
总之,soap扩展在安全保密方面是非常有用的.
分享到:
评论

相关推荐

    Soap协议详细介绍

    SOAP本身并没有定义任何应用程序语 义 ,如编程模型或特定语义的实现;实际上它通过提供一个有标准组件的包模型和在模块中编码数据的机制 ,定义了一个简单的表示应用程序语义的机制。这使 SOAP能够被用于从消息传递到...

    Jabber与SOAP协议Agent模型及其实现

    提出一种Jabber协议与SOAP协议的代理模型, 并用Java语言实 现了Jabber协议与SOAP协议的相互转换。该代理适用于基于Jabber协议的系统与其他应用系统的连接, 对 Jabber协议系统的功能进行了扩展, 解决了其他应用...

    论文研究-应用SOAP协议跨网络存取数据的实现.pdf

    简单对象访问协议(Simple Object Access Protocol,SOAP)通过一种...介绍了SOAP协议相关技术,重点论述了应用SOAP协议跨平台,跨局域网存取数据的实现过程,并对其优点进行了探讨。最后,讨论了进一步研究的工作。

    soap协议入门,简单细致

    SOAP本身并没有定义任何应用程序语义,如编程模型或特定语义的实现;实际上它通过提供一个有标准组件的包模型和在模块中编码数据的机制,定义了一个简单的表示应用程序语义的机制。这使SOAP能够被用于从消息传递到...

    简单对象访问协议(SOAP)初级指南

    SOAP(Simple Object Access Protocal) 技术有助于实现大量异构程序和平台之间的互操作性,从而使存在的应用能够被广泛的用户所访问。SOAP是把成熟的基于HTTP的WEB技术与XML的灵活性和可扩展性组合在了一起。  这...

    SOAP 经典教程

    • SOAP 用于应用程序之间的通信 • SOAP 是一种用于发送消息的格式 • SOAP 被设计用来通过因特网进行通信 • SOAP 独立于平台 • SOAP 独立于语言 • SOAP 基于 XML • SOAP 很简单并可扩展 • SOAP 允许您...

    soap 编程规范 实用

    SOAP是用在分散或分布的环境中交换信息的简单的协议,它是一个基于XML的协议,包括三个部分:封装定义了一个描述消息中包含什么内容以及如何处理它们的框架,编码规则用于表示应用程序定义的数据类型的实例,另外...

    煤炭企业中Web客户端程序解析与封装SOAP的探讨

    简单对象访问协议(SOAP)是一种标准化的通信协议,在煤炭企业的信息管理中,它提供一种简单、可扩展以及丰富的XML消息框架,被广泛应用于网络Web服务中。文章通过设计客户端程序调用Web服务的试验,发现客户端从SOAP中...

    Web-Service与SAP-ECC系统服务发布与调用

    注:SOAP协议(Simple Object Access Protocol,简单对象访问协议),它是基于XML的用于分散和分布式环境下网络信息交换的通讯协议。在此协议下,软件组件或应用程序能够通过标准的HTTP协议进行通讯。它的设计目标就是...

    开源C++应用服务器:CWSS 0.8.0

    CWSS简化了可移植及可扩展的应用系统的开发,并为其它应用 系统和系统提供了丰富的互操作性。CWSS拥有最高水平的可扩展性和可用性。CWSS内置标准通讯语言SOTP,轻松实现访问验证功能、负载平衡和群集功能,而且不...

    软件开发、软件工程技术规范集萃

    SOAP协议规范 IP协议(Internet Protocol) 传输控制协议 用户数据报协议(UDP) 三、软件工程类 计算机软件产品开发文件编制指南(GB 8567-88) 计算机软件配置管理计划规范(GB/T 12505-90) 计算机软件质量保证计划...

    Web Service详解

    其中,SOAP协议(Simple Object Access Protocal,简单对象访问协议)是一个用于分散和在分布式环境下交换网络信息的基于XML的通信协议。在此协议下,软件组件或应用程序能够通过标准的HTTP协议进行通信。它的设计...

    XFire_WebService开发例子

    注:SOAP协议(Simple Object Access Protocal,简单对象访问协议),它是一个基于XML的通讯协议用于分散和分布式环境下网络信息交换。在此协议下,软件组件或应用程序能够通过标准的HTTP协议进行通讯。它的设计目标...

    webservice指南电子书

    注:SOAP协议(Simple Object Access Protocal,简单对象访问协议),它是一个用于分散和分布式环境下网络信息交换的基于XML的通讯协议。在此协议下,软件组件或应用程序能够通过标准的HTTP协议进行通讯。它的设计...

    软件工程师的技术规范集萃

    SOAP协议规范 IP协议(Internet Protocol) 传输控制协议(Transmission Control Protocol, TCP) 用户数据报协议(UDP) 三、软件工程类 计算机软件产品开发文件编制指南 计算机软件配置管理计划规范 计算机软件...

    使用Java搭建Webservices应用程序结构.doc

    各应用程序通过网络协议和规定的一些标准数据格式(Http,XML,Soap)来访问Web Service,通过Web Service内部执行得到所需结果.Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web ...

    WebService技术及其应用实例论文

    其次介绍了WebService技术中的关键技术,其中包括可扩展性标记语言(XML)、简单对象访问协议(SOAP)、Web服务描述语言(WSDL)和统一描述、发现与集成(UDDI)注册中心。最后本文依据WebServices的技术原理、体系...

    ezService分布式应用快速开发工具

    6. 支持SOAP协议,提供一个ISAPI类型的Web Service,一个ASP.NET Web Service,可以直接将服务功能发布到Internet/Intranet,无须额外编程。 7. 未授权的ezService服务具备与授权版本完全相同的功能,仅会在执行时...

    DotNetOpenServer SDK:轻量级完全可扩展的客户端/服务器应用程序框架-开源

    与大多数应用程序服务器框架不同,这些应用程序框架是通过使用诸如JSON和XML之类的笨重ASCII数据格式的HTTP,REST和SOAP等缓慢,低效的无状态协议实现的,而DotNetOpenServer则是从头开始使用高效的有状态二进制...

    技巧:用JAX-RPC发送与接收SOAP消息

    最基本的操作就是对一个URL流执行println,不过这要求您理解太多有关SOAP协议的知识,并且要知道某个服务期望收到的SOAP消息是什么样,发出的又是什么样。我们无法很方便地从服务本身获得这些信息,因此这种方法的可...

Global site tag (gtag.js) - Google Analytics