构建安全的Xml Web Service系列之初探使用Soap头

简介: 原文:构建安全的Xml Web Service系列之初探使用Soap头    Xml Web Service 从诞生那天就说自己都么都么好,还津津乐道的说internet也会因此而进入一个新纪元,可5年多来,Xml Web Service并没有像当初宣扬的那样火起来,尽管在一些领域之内,也有人牛刀小试,但从整体而言,Service还并没有得到广泛的应用,原因有很多,有一些来源于目前各大厂商都坚持自己的service标准,不能形成统一,也有对现有的稳定系统不愿进行更改的原因,但还包括web service本身的原因,最明显的应该是两个:1) 安全,2)性能。
原文: 构建安全的Xml Web Service系列之初探使用Soap头

    Xml Web Service 从诞生那天就说自己都么都么好,还津津乐道的说internet也会因此而进入一个新纪元,可5年多来,Xml Web Service并没有像当初宣扬的那样火起来,尽管在一些领域之内,也有人牛刀小试,但从整体而言,Service还并没有得到广泛的应用,原因有很多,有一些来源于目前各大厂商都坚持自己的service标准,不能形成统一,也有对现有的稳定系统不愿进行更改的原因,但还包括web service本身的原因,最明显的应该是两个:1) 安全,2)性能。毕业设计的时候,写的是高性能web service的开发和应用,下面,我想用几篇文章来阐述一下有关xml web service安全的几个解决方案。欢迎各位大虾来砸。
    如何解决网络服务的安全问题,我主要从以下两个层面进行分析:
   1) 确保调用者的合法身份-保证来源的合法
   2) 在传输中不被非法监听和篡改。
当然还会有其他方面的安全隐患,希望大家能多多提出,我也好能进一步总结。
   如果您想更快的掌握本文提到的技术,您以前必须了解xml web service的工作原理,并且亲自开发并部署或者使用过Xml web service,只是您并不相信您部署的xml web service是安全的。
 本节先介绍一种最为简单的确保调用者合法的解决方案-将用户名和密码附加在Soap消息头部,在服务器端进行用户名密码验证。这种方式从解决了原网络服务不能针对特定对象产生响应的问题。但因为仍以明文格式
传输,所以不能有效地防止信息在传输过程中被偷窥,篡改或伪造。
  如果您以前已经使用了这种方法,请略过此篇文章,我下篇文章中将讲述其他方式,更加合理的解决方案,欢迎您继续关注。
   下面是实现此种解决方案的步骤,请您一步一步来
  第一步:首先您需要创建一个Xml Web Service的服务项目,创建方法如下
     打开visual studio 2005,在起始页上点击创建项目,选择visual C#中的Asp.Net web 服务应用程序,输入项目名称
  第二步:在该项目中创建一个扩展的SoapHeader对象MySoapHeader,如下
  

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif MySoapHeader
img_a6339ee3e57d1d52bc7d02b338e15a60.gifusing System;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Data;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Configuration;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.Security;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.UI;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.UI.WebControls;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.UI.WebControls.WebParts;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.UI.HtmlControls;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.Services.Protocols;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
namespace WebService1
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif    
public class MySoapHeader:SoapHeader
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif        
private string _userName;
img_33d02437d135341f0800e3d415312ae8.gif        
private string _pwd;
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
/**//// <summary>
img_33d02437d135341f0800e3d415312ae8.gif        
/// 用户名
img_105a1e124122b2abcee4ea8e9f5108f3.gif        
/// </summary>

img_33d02437d135341f0800e3d415312ae8.gif        public string UserName
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            
get
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                
return _userName;
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            
set
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                _userName 
= value;
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
/**//// <summary>
img_33d02437d135341f0800e3d415312ae8.gif        
/// 密码
img_105a1e124122b2abcee4ea8e9f5108f3.gif        
/// </summary>

img_33d02437d135341f0800e3d415312ae8.gif        public string Pwd
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            
get
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                
return _pwd;
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            
set
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                _pwd 
= value;
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

img_05dd8d549cff04457a6366b0a7c9352a.gif}

img_a6339ee3e57d1d52bc7d02b338e15a60.gif
第三步:创建一个Xml Web Service,另添加一个要求使用SoapHeader的网络服务方法
  
img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif WebService
img_a6339ee3e57d1d52bc7d02b338e15a60.gifusing System;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Data;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Collections;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.Services;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Web.Services.Protocols;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.ComponentModel;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
namespace WebService1
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
/**//// <summary>
img_33d02437d135341f0800e3d415312ae8.gif    
/// Service1 的摘要说明
img_105a1e124122b2abcee4ea8e9f5108f3.gif    
/// </summary>

img_33d02437d135341f0800e3d415312ae8.gif    [WebService(Namespace = "http://tempuri.org/")]
img_33d02437d135341f0800e3d415312ae8.gif    [WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1)]
img_33d02437d135341f0800e3d415312ae8.gif    [ToolboxItem(
false)]
img_33d02437d135341f0800e3d415312ae8.gif    
public class Service1 : System.Web.Services.WebService
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif        
public MySoapHeader header = new MySoapHeader();        
img_33d02437d135341f0800e3d415312ae8.gif        [WebMethod]
img_33d02437d135341f0800e3d415312ae8.gif        [SoapHeader(
"header")]       
img_33d02437d135341f0800e3d415312ae8.gif        
public string HelloWorld()
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            
if (header == null)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                
return "您没有设置SoapHeader,不能正常访问此服务!";
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            
if (header.UserName != "jillzhang" || header.Pwd != "123456")
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                
return "您提供的身份验证信息有误,不能正常访问此服务!";
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            
return "Hello World";
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

img_05dd8d549cff04457a6366b0a7c9352a.gif}

img_a6339ee3e57d1d52bc7d02b338e15a60.gif
  第四步:创建一个调用Xml Web Service的Console应用程序,如下:
img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif TestConsole
img_a6339ee3e57d1d52bc7d02b338e15a60.gifusing System;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Collections.Generic;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using System.Text;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
namespace ConsoleApplication1
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif    
class Program
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif       
img_33d02437d135341f0800e3d415312ae8.gif        
static void Main(string[] args)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            localhost.Service1 ws 
= new ConsoleApplication1.localhost.Service1();
img_33d02437d135341f0800e3d415312ae8.gif            
//ws.MySoapHeaderValue = new ConsoleApplication1.localhost.MySoapHeader();
img_33d02437d135341f0800e3d415312ae8.gif            
//ws.MySoapHeaderValue.UserName = "jillzhang";
img_33d02437d135341f0800e3d415312ae8.gif            
//ws.MySoapHeaderValue.Pwd = "123456";
img_33d02437d135341f0800e3d415312ae8.gif
            Console.WriteLine(ws.HelloWorld());
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

img_05dd8d549cff04457a6366b0a7c9352a.gif}

img_a6339ee3e57d1d52bc7d02b338e15a60.gif
  下面的分析,对于大家来说,应该是最重要的,很多人不清楚SoapHeader的工作原理,为什么这么怪异的写法竟能产生神奇的效果,下面我将不同情形下的Soap消息解析出来,大家仔细观察这个信息,并可以清晰地掌握了SoapHeader的工作原理了.
首先,先看看没有设置SoapHeader的情况下,Soap消息为:
 
img_a6339ee3e57d1d52bc7d02b338e15a60.gif -----Soap请求 在 2007年05月22日 12时39分40秒
img_a6339ee3e57d1d52bc7d02b338e15a60.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 >< HelloWorld  xmlns ="http://tempuri.org/"   /></ soap:Body ></ soap:Envelope >
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
img_a6339ee3e57d1d52bc7d02b338e15a60.gif-----Soap响应 在 2007年05月22日 12时39分40秒
img_a6339ee3e57d1d52bc7d02b338e15a60.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 > 您提供的身份验证信息有误,不能正常访问此服务! </ HelloWorldResult ></ HelloWorldResponse ></ soap:Body ></ soap:Envelope >
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
再看看在设置了SoapHeader之后的Soap的请求和响应信息
img_a6339ee3e57d1d52bc7d02b338e15a60.gif -----Soap请求 在 2007年05月22日 12时42分20秒
img_a6339ee3e57d1d52bc7d02b338e15a60.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 >
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
img_a6339ee3e57d1d52bc7d02b338e15a60.gif-----Soap响应 在 2007年05月22日 12时42分20秒
img_a6339ee3e57d1d52bc7d02b338e15a60.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 >
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
大家可以比较前后两个Soap消息的异同,会发现,加了SoapHeader的请求SoapMessage比没有加的多了一个节
点<soap:Header>正是通过这个节点,SoapMessage将信息传递给了网络服务端,网络服务端便可以从中解析出来,并加以处理,从上面的SoapMessage中,我们也看出,用户名和密码是以明文的格式传输的,这样,SoapHeader就更像Http协议中的Cookie了,我们可以参考Cookie的使用,来扩展SoapHeader,让它变得更加安全些,但总的看来,通过直接设置SoapHeader的方法提高安全性还是有一定限制的。在安全不是特别重要的应用情形中,推荐采用此种解决方案,因为它方便快捷,灵活易用。
有关Cookie的信息,请参考前期文章: Cookie-天使还是恶魔?
下一节,我将介绍一下,如何获取SoapMessage.
目录
相关文章
|
2月前
|
XML JSON 前端开发
【Web前端揭秘】XML与JSON:数据界的双雄对决,你的选择将如何改写Web世界的未来?
【8月更文挑战第26天】本文深入探讨了XML和JSON这两种广泛使用的数据交换格式在Web前端开发中的应用。XML采用自定义标签描述数据结构,适用于复杂层次数据的表示,而JSON则以键值对形式呈现数据,更为轻量且易解析。通过对两种格式的示例代码、结构特点及应用场景的分析,本文旨在帮助读者更好地理解它们的差异,并根据实际需求选择最合适的数据交换格式。
50 1
|
2月前
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
|
2月前
|
关系型数据库 MySQL Linux
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
|
2月前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
37 0
|
2月前
|
Shell PHP Windows
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
|
2月前
|
Linux 应用服务中间件 网络安全
【Azure 应用服务】查看App Service for Linux上部署PHP 7.4 和 8.0时,所使用的WEB服务器是什么?
【Azure 应用服务】查看App Service for Linux上部署PHP 7.4 和 8.0时,所使用的WEB服务器是什么?
|
2月前
【Azure 应用服务】通过 Web.config 开启 dotnet 应用的 stdoutLog 日志,查看App Service 产生500错误的原因
【Azure 应用服务】通过 Web.config 开启 dotnet 应用的 stdoutLog 日志,查看App Service 产生500错误的原因
|
2月前
|
Linux Python
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
|
2月前
|
存储 安全 网络安全
【Azure 环境】使用Azure中的App Service部署Web应用,以Windows为主机系统是否可以启动防病毒,防恶意软件服务呢(Microsoft Antimalware)?
【Azure 环境】使用Azure中的App Service部署Web应用,以Windows为主机系统是否可以启动防病毒,防恶意软件服务呢(Microsoft Antimalware)?
|
2月前
|
存储 Linux 网络安全
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志