天天看点

WSE3.0构建Web服务安全(4):MTOM消息传输优化和文件上传、下载

     MTOM消息优化传输机制主要应用于大量数据的传输,很多文章中也直接得出结论:使用MTOM文件传输效率高。为什么MTOM的数据传输效率会比别的方式要高?MTOM真的如此完美吗,它有什么不足?什么情况下使用MTOM?这些疑问,本文WSE3.0构建Web服务安全系列文章的第4节:MTOM消息优化传输机制和文件上传、下载--将为您一一解答。本节结构为1.MTOM基础概念2.WSE3.0工具配置MTOM3.代码实现与分析4.总结。最后附上实现代码供大家参考。

    WSE3.0中引入MTOM机制,给我们借助WSE框架实现大量数据的交互带来显著的益处。在WSE 3.0中,我们可以使用MTOM用于服务器端和客户端传递消息,另外的好处就是,WSE 3.0M允我们在传递大数据量时使用WSE 3.0消息层的安全性机制,借助WSE3.0的安全框架,我们不仅可以验证用户的合法性,还可以对消息进行加密,不仅能够保证数据的安全,还可以实现大数据量的高效传输。

1.【MTOM基础概念】

   提到MTOM消息优化传输机制,通常的实验结果是使用MTOM传输数据会提高大约33%的性能。 消息传输优化机制 (MTOM) 标准允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数据随消息一起传送。MTOM 消息会打包为多部分/相关 MIME 序列,放在SOAP 消息中一起传送。

     我们需要了解一些相关的概念。什么是BASE64编码、MTOM消息优化传输机制、MIME。这些对于我们理解MTOM消息优化传输机制问题非常的必要。下面就来做下介绍。

1.1【BASE64编码】

     BASE64编码 的原理很简单,其方法是,将输入数据流每次取6 bit(每bit代表1位二进制),不足6bit的补0,这样,每3个8位字节将编码为4个6位字节(3×8 → 4×6);不满4个字节的以“=”填充。其实这4个六位字节 仍然是8位,只不过高两位被设置为0。当一个字节只有6位有效时,它的取值空间为0 到 2的6次方减1 即63,也就是说被转换的Base64编码的每一个编码的取值空间为(0~63)。

  这样就可以将3个8位字节,转换为4个字节,这4个转换的字节都可以映射到字符中。也即数据都可以使用字符编码代替。 因为转换后的字符串要比原来的多一个字节,长1/3。因此编码后的数据长度增加到4/3倍。这里也是为什么使用SOAP消息效率比MTOM低的原因。因为SOAP使用XML语言进行消息传递,XML是基于BASE64编码的语言。

1.2【MIME】

     MIME表示多用途Internet邮件扩允协议。MIME扩允了基本的面向文本的Internet邮件系统,以便可以在消息中包含二进制附件。MIME(Multipurpose Internet Mail Extentions),一般译作"多用途的网络邮件扩充协议"。顾名思义,它可以传送多媒体文件。 MIME (Multipurpose Internet Mail Extensions,多目的Internet邮件扩展)是创建用于电子邮件交换,网络文档,及企业网和Internet上的其他应用程序中的文件格式的规范。

1.3【MTOM消息优化传输】

    MTOM 全称Message Transmission Optimization Mechanism,即消息传输优化机制。它提出的模型适用于大量数据的交互情况。针对Base64编码情况带来的开销提出的解决方案。当数据量小的时候,SOAP依然使用XML进行消息的传递。

     但是在大量数据情况下,如果数据依然进行Base64编码,会带来33%的额外开销,这样的情况对于大量数据交换的情况是无法容忍的。MTOM 就是针对SOAP 消息传输的基础上提出的改进办法。对于大量数据的传递,不会进行进行Base64编码,而是直接以附件的二进制原始数据的形式封装在SOAP消息的MIME 部分,进行传输。SOAP 消息通过指向随其发送的 MIME 部分来引用二进制内容,另外包括SOAP基本的XML 数据,这些还是Base64编码。因为此模型与简单邮件协议SMTP 模型基本一致。

      MTOM通过简化大量数据的编码过程,从而提高数据的处理效率。因为SOAP消息等必要的信息,MTOM 也有一些必要的开销。MTOM仅在二进制数据元素的大小超过大约 1 KB 时,才能体现出其优势。

2.【WSE3.0工具配置MTOM】

     在WSE3.0项目中使用MTOM消息传输优化机制非常的方便,我们可以使用WSE 3.0配置工具分别为Web 服务和Client客户端设置启用MTOM,生成相应的策略文件,WSE3.0机制会根据策略对消息传输使用MTOM(也可以通过代码实现) 。

    数据使用字节流byte[]数组在客户端和服务端进行传输,简单的例子就是消息的交互和文件的上传和下载操作。本次配置基本介绍的情况也是借助WSE3.0的安全机制实现文件的安全传输。

     2.1首先使用WSE 3.0配置工具设置服务端消息传输策略。如图:

客户端设置为on,要求客户端使用MTOM机制进行数据传输。服务端设置为Optional,表示可选,服务端既支持MTOM又可以不支持MTOM编码的消息。适用性强。

此种情况即服务端会根据客户端的请求类型来决定是否启用MTOM机制进行数据传递.如果客户端适用MTOM编码,则服务会启用MTOM处理消息。如果设置为Always,服务端会一直使用MTOM机制进行消息的传递。一般不推荐使用这个方式。OFF即一直不使用MTOM机制进行消息传递。64为最大附加二进制文件的个数。最后表示需要首先使用SOAP消息封装。

The <code>optional</code> mode is the default settings. In this mode the WSE processes the incoming SOAP messages whether or not they are <code>MTOM</code> encoded. This gives much more flexibility to web services that are not only dealing with large amount of data. With optional the client is the one who decide whether to use <code>MTOM</code> or not, if the client application request to use <code>MTOM</code> the web service will use <code>MTOM</code>.

In <code>always</code> mode all incoming and outgoing SOAP messages must be <code>MTOM</code> encoded. When a SOAP request is received that is not encoded using <code>MTOM</code>, an HTTP error 415: "Media unsupported" is returned to the sender. This option is ideal for Web Services that only deal with large amount of data.

In <code>never</code> mode all incoming SOAP messages must not be <code>MTOM</code> encoded. When a SOAP request is received that is encoded using <code>MTOM</code>, an HTTP error 415: "Media unsupported" is returned to the sender. That means the client application should never use <code>MTOM</code>.

对应的配置文件为:

    &lt;messaging&gt;

      &lt;mtom serverMode="optional" clientMode="On" /&gt;

    &lt;/messaging&gt;

     2.2客户端的设置与服务端类似:

客户端配置文件的代码如下:

      &lt;mtom clientMode="On" serverMode="optional" /&gt;

3.【代码实现与分析】

    进行完毕配置以后我们来具体进入代码的开发阶段。这里给出了使用MTOM上传照片的例子,一个使用了证书加密图片上传。先给出服务端的实现,包括两个服务类:WSE3MTOMService和WSE3MTOMSecureService。方法都是二进制字节数据流的传递。

3.1WSE3MTOMService直接实现基于MTOM机制的图片上传和下载方法,具体实现如下:

//WSE 3.0 Samples中的MTOM示例演示了:不加密上传、下载文件、

[WebService(Namespace = "http://www.cnblogs.com/frank_xl/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class WSE3MTOMService : System.Web.Services.WebService

{

    public WSE3MTOMService()

    {

    }

    //此方法返回不加密的字节数组,下载文件

    [WebMethod]

    public byte[] DownLoadFile(string fileName)

        byte[] file = new byte[1024];

        String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + fileName;

        file = File.ReadAllBytes(filePath);

        return file;

    //上传文件,传回2进制数据

    public void UpLoadFile(byte[] file)

        String filePath = AppDomain.CurrentDomain.BaseDirectory + @"App_Data\" + "FrankXuLei.gif";

        if (File.Exists(filePath))

            File.Delete(filePath);

        File.WriteAllBytes(filePath, file);

}

3.2WSE3MTOMSecureService定义了一个文件下载的方法。具体如下:

//WSE 3.0 Samples中的MTOM示例演示了:加密上传、下载文件、

//Returns binary data secured via the ServerPolicy in the wse3policyCache.config policy file

[Policy("ServerPolicy")]

public class WSE3MTOMSecureService : System.Web.Services.WebService

    public WSE3MTOMSecureService()

    //T通过服务端 X509 证书加密

    // MTOM可以使用WS-Security安全协议.

    public byte[] DownLoadFileWithSecurity(string fileName)

        byte[] file = null;

        file = File.ReadAllBytes(filePath);//从文件里读取字节流

3.3客户端建立控制台应用程序,添加对Web服务的引用。实例化连个代理服务类,进行文件的上传和下载。具体代码如下:

//直接进行数据传输,不需要加密

        public void DownLoadFile(String fileName)

        {

            //实例化服务代理类

            WSE3MTOMServiceWse serviceproxy = new WSE3MTOMServiceWse();

            //or alternatively set the RequireMtom property on the proxy

            //serviceproxy.RequireMtom = true;

            //获取文件二进制字节流

            byte[] loadFile = serviceproxy.DownLoadFile(fileName);

            //打印数据信息

            Console.WriteLine("File Name: {0}", fileName);

            Console.WriteLine("File has been downloaded without security sucessfully from Server: {0}", loadFile.Length);

            //保存文件

            String filePath = AppDomain.CurrentDomain.BaseDirectory + fileName;

            Console.WriteLine("");

            if (File.Exists(filePath))

                File.Delete(filePath);

            File.WriteAllBytes(filePath, loadFile);

        }

        //安全方式下载文件

        public void DownLoadFileSecure(String fileName)

            WSE3MTOMSecureServiceWse serviceproxy = new WSE3MTOMSecureServiceWse();

            //Set anonymousForCertificateSecurity policy assertion when calling

            //this secure service

            serviceproxy.SetPolicy("ClientPolicy");

            byte[] loadFile = serviceproxy.DownLoadFileWithSecurity(fileName);

            Console.WriteLine("File has been downloaded with security sucessfully from Server: {0}", loadFile.Length);

            String filePath = AppDomain.CurrentDomain.BaseDirectory + "Secure_"+ fileName;

                File.WriteAllBytes(filePath, loadFile);

        //测试非加密安全上传文件

        public void UpLoadFile(String fileName)

            //实例化服务代理

            //读取文件数据

            byte[] upFile = File.ReadAllBytes(filePath);

            //调用方法传输数据

            serviceproxy.UpLoadFile(upFile);

            //输出上传文件信息

            Console.WriteLine("File has been uploaded sucessfully from Client: {0}", upFile.Length);

运行结果如图:

    首先是上传一个文件到服务器端,然后进行下载操作。均显示成功。可以在程序的运行目录下找到下载的新文件。

4.【总结】

    通过以上的介绍和学习,我们知道了一下结论:

1.MTOM机制会效率提升1/3.原因:正常文本 XML 使用 Base64 对二进制数据进行编码,这要求每三个字节对应四个字符,从而使得数据的大小增加三分之一。MTOM 能够以原始字节形式传输二进制数据,这会缩短编码/解码时间并生成较小的消息。

2.使用的场合:MTOM适合大量的数据交换,通常是大量数据情况下才有优势, 如上传文档和图片,目的在于优化对较大的二进制负载的传输。

3.缺陷:对于较小的二进制负载来说,使用 MTOM 发送 SOAP 消息会产生显著的开销。

   Web服务驻留在IIS外,可以由系统服务、控制台程序等托管的方式比较简单,大家可以参考微软的例子,这个WCF里也有类似的寄宿宿主的概念。其实有许多相似之处。

   最后在准备《WSE3.0构建Web服务安全》系列文章的过程中,我也收获不少,也希望本系列文能给您的学习带来一些帮助。包括我之前的《WCF分布式开发必备知识》系列都是学习WCF分布式重要知识点的总结。并且全部给出了详细的代码实现和注释。方便大家的学习和实际项目的应用。下面我们将正式进入WCF分布式开发的学习阶段,我会继续给出系统的介绍和详细的实现代码。希望有兴趣的朋友继续关注~谢谢

参考资料:

1.BASE64编码基于十进制的实现方法

2.MTOM编码 MSDN

 本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/320503,如需转载请自行联系原作者

继续阅读