Web服务(WS)安全教程及SOAP示例

什么是 WS 安全性?

WS 安全性是一项标准,旨在解决 Web 服务数据交换过程中的安全性问题。这是 SOAP 的一项关键功能,使其在创建 Web 服务方面非常受欢迎。

在任何 Web 应用程序中,安全性都是一项重要功能。由于几乎所有 Web 应用程序都暴露在互联网上,因此 Web 应用程序始终存在安全威胁的可能性。因此,在开发基于 Web 的应用程序时,始终建议确保应用程序在设计和开发时就考虑到了安全性。

安全威胁与对策

为了理解可能对 Web 应用程序构成威胁的安全威胁,让我们看一个简单的 Web 应用程序场景,看看它是如何在安全性方面工作的。

HTTP 可用的安全措施之一是 HTTPS 协议。HTTPS 是客户端和服务器之间在 Web 上进行安全通信的方式。HTTPS 使用安全套接字层或 SSL 来实现安全通信。客户端和服务器都将拥有一个数字证书,以便在客户端和服务器之间进行任何通信时将它们识别为真实。

Security Threats and Countermeasure

在客户端和服务器之间的标准 HTTPS 通信中,会发生以下步骤:

  1. 客户端通过客户端证书向服务器发送请求。当服务器看到客户端证书时,它会在其缓存系统中记下,以便它知道响应只能返回给此客户端。
  2. 然后,服务器通过发送其证书来向客户端进行身份验证。这确保客户端正在与正确的服务器进行通信。
  3. 此后,客户端和服务器之间的所有通信都经过加密。这确保了如果其他用户试图破坏安全并获取所需数据,他们将无法读取它,因为它已被加密。

但是,上述安全类型并非在所有情况下都有效。有时客户端可以与多个服务器通信。下面的示例显示了一个客户端同时与数据库和 Web 服务器通信。在这种情况下,并非所有信息都可以通过 https 协议。

Security Threats and Countermeasure

这就是 SOAP 通过制定 WS 安全性规范来克服此类障碍的地方。通过此规范,所有安全性相关数据都定义在 SOAP 标头元素中。

标头元素可以包含以下信息:

  1. 如果 SOAP 主体内的消息已使用任何安全密钥签名,则可以在标头元素中定义该密钥。
  2. 如果 SOAP 主体内的任何元素已加密,标头将包含必要的加密密钥,以便在消息到达目的地时可以解密。

在多服务器环境中,上述 SOAP 身份验证技术通过以下方式提供帮助:

  • 由于 SOAP 主体已加密,因此只有托管 Web 服务的 Web 服务器才能解密它。这是因为 SOAP 协议的设计方式。
  • 假设消息以 HTTP 请求的形式传递给数据库服务器,则无法解密,因为数据库没有正确的机制来执行此操作。
  • 直到请求实际作为 SOAP 协议到达 Web 服务器,它才能解密消息并将其适当的响应发送回客户端。

我们将在后续主题中介绍如何使用 WS 安全性标准来SOAP

Web 服务安全标准

如前一节所述,WS-Security 标准围绕在 SOAP 标头中包含安全性定义。

SOAP 标头中的凭据通过 2 种方式进行管理。

首先,它定义了一个名为 UsernameToken 的特殊元素。这用于将用户名和密码传递给 Web 服务。

另一种方式是通过 BinarySecurityToken 使用二进制令牌。这用于加密技术(如 Kerberos 或 X.509)使用的场景。

下图显示了 WS 安全性中安全性模型的工作流程。

Web Service Security Standards

以下是上述工作流程中发生的步骤:

  1. 可以从 Web 服务客户端将请求发送到安全令牌服务。该服务可以是中间 Web 服务,专门用于向实际 SOAP Web 服务提供用户名/密码或证书。
  2. 然后将安全令牌传递给 Web 服务客户端。
  3. Web 服务客户端然后调用 Web 服务,但这一次,确保安全令牌嵌入在 SOAP 消息中。
  4. Web 服务随后了解带有身份验证令牌的 SOAP 消息,然后可以联系安全令牌服务以查看安全令牌是否真实。

下面的代码段显示了 WSDL 文档中身份验证部分 的格式。现在,根据下面的代码段,SOAP 消息将包含 2 个额外的元素,一个是用户名,另一个是密码。

<xs:element name="UsernameToken">  
	<xs:complexType>       
		<xs:sequence>           
			<xs:element ref="Username"/>         
			<xs:element ref="Password" minOccurs="0"/>        
		</xs:sequence>       
	<xs:attribute name="Id" type="xs:ID"/>    
</xs:complexType></xs:element>

当 SOAP 消息实际在客户端和服务器之间传递时,包含用户凭据的消息部分可能看起来像上面所示。wsse 元素名称是为 SOAP 定义的特殊元素名称,表示它包含基于安全性的信息。

如何构建安全的 Web 服务

现在让我们来看一个 SOAP Web 服务安全示例。我们将基于之前在 SOAP 章节中演示的示例构建 Web 服务安全性,并为其添加安全性层。

在我们的示例中,我们将创建一个简单的 Web 服务,用于将字符串返回给调用 Web 服务的应用程序。但这一次,当调用 Web 服务时,需要向调用方提供凭据。让我们按照以下步骤创建 SOAP Web 服务并添加安全性定义。

步骤 1) 第一步是创建一个空的 Asp.Net Web 应用程序。在 Visual Studio 2013 中,单击菜单选项 文件->新建项目。

Build Secure Web Services

单击“新建项目”选项后,Visual Studio 将会显示另一个对话框,用于选择项目类型并提供项目的必要详细信息。这将在下一步中进行说明。

步骤 2) 在此步骤中,

  1. 确保首先选择 ASP.NET Web 应用程序的 C# Web 模板。为了创建 Web 服务项目,项目必须是此类型。通过选择此选项,Visual Studio 将执行必要的步骤来添加任何基于 Web 的应用程序所需的必要文件。
  2. 为您的项目命名,在本例中命名为“webservice.asmx。”。然后,确保提供项目文件将存储的位置。

Build Secure Web Services

完成后,您将在Visual Studio 2013的解决方案资源管理器中看到已创建的项目文件。

Build Secure Web Services

步骤 3) 在此步骤中,

我们将向我们的项目添加一个 Web 服务文件。

  1. 首先右键单击项目文件,如下图所示

Build Secure Web Services

  1. 右键单击项目文件后,您可以选择“添加->Web 服务 (ASMX)”选项来添加 Web 服务文件。只需为 Web 服务文件名提供“Tutorial Service”即可。

    Build Secure Web Services

上述步骤将提示一个对话框,您可以在其中输入 Web 服务文件的名称。因此,在下面的对话框中,将“TutorialService”作为文件名输入。

Build Secure Web Services

步骤 4) 将以下代码添加到您的 Tutorial Service asmx 文件中。下面的代码片段用于添加一个自定义类,该类将用于在生成 SOAP 消息时更改 SOAP 标头。由于我们现在要向 SOAP 标头添加安全性凭据,因此此步骤是必需的。

Build Secure Web Services

		return "This is a Guru99 Web Service";
	}
	
	public class AuthHeader : SoapHeader
	{
		public string UserName;
		public string Password;

	}
}

代码解释:

  1. 我们现在正在创建一个名为 AuthHeader 的单独类,它属于 SoapHeader 类。每当您想要更改传递到 SOAP 标头的内容时,都需要创建一个使用 .Net 内置 SoapHeader 类的类。通过自定义 SOAPheader,我们现在可以在调用 Web 服务时传递“用户名”和“密码”。
  2. 然后我们定义“UserName”和“Password”类型的变量,它们都是字符串类型。它们将用于保存传递给 Web 服务的用户名和密码的值。

步骤 5) 作为下一步,需要将以下代码添加到同一个 TutorialService.asmx 文件 中。此代码实际定义了我们 Web 服务的功能。此函数将字符串“This is a Guru99 Web service”返回给客户端。但这一次,只有当客户端应用程序向 Web 服务提供凭据时,字符串才会被返回。

Build Secure Web Services

public class TutorialService : System.Web.Services.WebService
{ 
	public AuthHeader Credentials; 
	
	[SoapHeader("Credentials")] 
	
	[WebMethod]
	public string Guru99WebService()
	{ 
	
		if (Credentials.UserName.ToLower() != "Guru99" ||
		Credentials.Password.ToLower() != "Guru99Password") 
		{
			throw new SoapException("Unauthorized",
			SoapException.ClientFaultCode);
		}
		eise
		return "This is a Guru99 Web service";
	}

代码解释:

  1. 在这里,我们创建了 AuthHeader 类的一个对象,该类在前面的步骤中创建。此对象将传递给我们的 Guru99Webservice,其中可以仔细检查用户名和密码。
  2. 现在使用 [SoapHeader] 属性来指定调用 Web 服务时需要传递用户名和密码。
  3. 在此代码块中,我们实际上正在检查调用 Web 服务时传递的用户名和密码。如果用户名等于“Guru99”,密码等于“Guru99Password”,则将消息“This is a Guru99 Web service”传递给客户端。否则,如果传递了错误的用户名和密码,则会向客户端发送错误。

如果代码成功执行,在浏览器中运行代码时将显示以下输出。

输出

Build Secure Web Services

上面显示的是程序运行时生成的输出,意味着 Web 服务现已可用。让我们点击“服务描述”链接。

Build Secure Web Services

从服务描述中,您现在可以看到用户名和密码是 WSDL 文件 的元素。调用 Web 服务时需要发送这些参数。

Web 服务安全最佳实践

在处理 Web 服务时,应注意以下安全注意事项:

1. 审计和日志管理 – 使用应用程序日志记录所有发往 Web 服务的请求。这提供了关于谁调用了 Web 服务的详细报告,并在发生任何安全漏洞时有助于影响分析。

2. Web 服务调用流程 – 尝试记录 Web 服务中的调用流程。默认情况下,应用程序可以通过身份验证令牌在这些 Web 服务之间传递调用多个 Web 服务请求。所有 Web 服务之间的调用都需要被监控和记录。

3. 敏感信息 – 不要将密码、信用卡号或任何其他机密信息包含在日志条目中。如果事件包含任何此类信息,则在记录之前需要将其丢弃。

4. 跟踪业务运营 – 跟踪重要的业务运营。例如,仪器化您的应用程序以记录对特定敏感方法和业务逻辑的访问。以在线购物应用程序为例。典型的应用程序包含多个步骤,例如选择要购买的商品、购物车中的商品以及最终购买。此整个业务工作流程需要由 Web 服务跟踪。

5. 正确的身份验证 – 身份验证是客户端通过一组凭据向 Web 服务建立其身份的机制,这些凭据可以证明该身份。用户凭据永远不应被存储,因此,如果使用 WS Security 调用 Web 服务,则需要注意 Web 服务不应存储 SOAP 标头中传递的凭据。这些应由 Web 服务丢弃。

摘要

  • SOAP 提供了一个附加层,称为 WS Security,用于在调用 Web 服务时提供额外的安全性。
  • WS Security 可以通过简单的用户名或密码调用,也可以与二进制证书结合用于身份验证。
  • 我们已经看到,在 .Net 中,我们可以自定义 Web 服务,使其能够通过 SOAP 标头元素传递用户名和密码。