基本和简要身份验证都使用质询-响应机制。正因为如此,在 Web 方法调用发生之前,客户端和接收器之间将发送多次请求和响应。在基本身份验证中,质询和响应的速度都相当快。事实上,如果客户端知道需要基本身份验证,它会提早提供基本凭据。这种提速可以是需要验证服务器证书并建立会话密钥的、基于 SSL 的连接中的临界值。在简要身份验证中,在凭据被加密前,需要交换 nonce。同样,在 Web 服务代码被执行之前需要执行一些握手操作。
要针对 Web 服务强制启用这些项,只需要在“身份验证方法”对话框中选中相应的框即可。如果您确认只需要获取已经过身份验证的用户,请确保取消选中“匿名访问”复选框。完成这一步后,您便可以在服务器端进行以下操作:
- 搜索调用者。
- 使用代码访问安全性限制调用者可以调用的方法。
以下 Web 服务返回当前的调用者信息:
[WebMethod] public string WhoAmI() { return "正在作为用户运行: " + Thread.CurrentPrincipal.Identity.Name; } |
我们将修改一个调用该 Web 服务的简单的控制台应用程序。开始时,客户端如下所示:
static void Main(string[] args) { localhost.Sample svc = new localhost.Sample(); try { Console.WriteLine( svc.WhoAmI() ); } catch ( Exception ex ) { Console.WriteLine( ex.ToString() ); } finally { svc.Dispose(); } }
|
如果没有对 Web 服务/应用程序应用安全保护,Main 函数将打印以下信息:

图 4:无安全保护运行,因而也没有身份标识
如果您通过图 3 中的对话框关闭匿名访问,客户端将无法访问 Web 服务。相反,将显示以下错误消息:
System.net.WebException: 请求失败,HTTP 状态 401: 访问被拒绝。
为什么会是这样呢?默认情况下,Web 服务代理不包含任何关于调用者或要传递的凭据的信息。因为不能验证自己的身份,调用 Web 方法的尝试失败,并且引发异常。如果您想为当前用户传递正确的凭据,最简单的方法是沿着当前用户的默认凭据传递。客户端中的
try 块需要进行修改才能读取:
svc.Credentials = System.Net.CredentialCache.DefaultCredentials; Console.WriteLine( svc.WhoAmI() ); |
它允许代理访问 Web 方法,因为它可以携带当前用户的凭据并将其提供给质询时的 Web 方法。Web 服务返回以下结果:
作为以下用户运行 : REDMOND\sseely
这将同时使用基本和简要身份验证。身份验证信息只对一个 Web 服务调用有效。换句话说,Web 服务代码不能调用其他 Web 服务,不能使用这些机制扮演调用者。请记住,如果您选择基本身份验证,则还应该为该文件请求一个 SSL 连接,以避免用户的身份被泄漏给监视连接的实体。有时,您可能需要使用不同于当前用户的身份标识来访问 Web 服务。那该怎么做呢?您可以“手动”设置凭据。
假设在本地 Web 服务器
sseely2 上有一个用户名为
Example,其密码为
Test$123。要手动设置凭据,必须创建一个
CredentialCache。使用
CredentialCache 的代码需要使用
NetworkCredential 对象填充高速缓存。当向高速缓存添加
NetworkCredential 时,代码需要指定返回指定凭据时所使用的 URL/身份验证组合类型。有可能使用多个站点的标识信息来填写高速缓存,并使高速缓存针对各站点和身份验证类型智能地返回正确的凭据。要将高速缓存设置为针对来自 Web 服务的基本身份验证质询发送正确的凭据,请使用以下代码:
| localhost.Sample svc = new localhost.Sample(); try { CredentialCache credCache = new CredentialCache(); NetworkCredential netCred = new NetworkCredential( "Example", "Test$123", "sseely2" ); credCache.Add( new Uri(svc.Url), "Basic", netCred ); svc.Credentials = credCache; Console.WriteLine( svc.WhoAmI() ); |
当在 URL 中传递,以在包含
credCache.Add 的行上使用时,您会发现 URL 是从 Web 服务中得到的,而不是被硬编码或从其他源获取的。我喜欢用这种方法将调用编写到
Add 方法中,因为这样最省事,又可以保证 Web 服务端点和调用
Add 所使用的端点相同。 如果您想为简要身份验证使用相同的凭据,则向凭据高速缓存添加信息的行将读取:
credCache.Add( new Uri(svc.Url), "Digest", netCred );
基本身份验证将对在本地计算机注册或在目录中注册的用户起作用。简要身份验证只接受在信任的 Windows 域中注册的用户。
另一种验证 Web 服务调用者的方法是通过 SSL 执行相互身份验证。SOAP 消息的发送者和接收者可以交换证书并互相验证。服务器如果具有 SSL 功能,则将具有证书。如果以相同的形式向客户端签发了证书,则客户端也将具有证书。如果您已经具有一个证书服务器,您需要给自己签发一个证书,然后通过图 2 所示的对话框将证书映射到您的用户帐户中。
如果您确实有可用的证书,则可以通过控制面板中的“Internet 选项”小程序访问这些证书。访问此小程序的最简便的方法是通过 Microsoft® Internet Explorer。如果您没有安装证书,而现在想获取一个。只需打开 Internet Explorer,浏览到已安装证书服务器的 Windows 服务器。您所需的 URL 为 http://
machine_name/certsrv。按照屏幕上的说明来请求和安装客户证书。下一步,在 Internet Explorer 的“工具”菜单中,单击“Internet 选项”,单击“内容”选项卡,然后单击“证书”。将显示一个与图 5 类似的对话框。

图 5:“证书”对话框
您需要导出一个证书,以便可以被 Web 服务代理身份验证使用。要导出证书,请单击“导出”打开“证书导出向导”。在向导中,单击“下一步”接受所有默认选项,然后选择一个写入证书的文件名。在我的示例中,我将证书保存到 c:\temp\secSample.cer 中。单击“下一步”,然后单击“完成”。现在,我们需要将该证书与某个特定用户关联起来。
- 重复执行请求 SSL 所需的步骤,以确保一个或所有 Web 服务的安全。
- 选择“启用客户证书映射”复选框,并单击“编辑”。
- 在“一对一映射”选项卡上,单击“添加”。
- 选择 c:\temp\secSample.cer
- 在“映射到帐户”对话框中,设置以下各项:
- “映射名”:HTTP 示例映射
- “帐户”:选择一个用户帐户。在我的示例中,我选择的是 sseely2\Example。
- “密码”:映射到帐户密码。在我的示例中,我输入的是 Test$123。 如果证书身份和与证书关联的身份不匹配,那没有关系。将证书匹配到身份标识时,服务器只在存储区中查找与接收到的证书完全匹配的另一个证书。为什么是这样呢?个人也可能具有由公共证书颁发机构签发的客户证书。使用 SSL 客户身份验证时,服务器可以将证书映射到主机中的某个身份标识,而不需要与证书颁发者以任何方式发生关联。
- 单击以确认密码,再单击三次“确定”关闭对话框。
现在,您需要在 IIS 中设置其他选项。首先需要清除所有可用的身份验证方法,以确保受保护的资源(.asmx 文件或虚拟目录)具有图 6 所示的权限设置。

图 6:所有身份验证方法都被清除
然后,需要客户证书,如图 7 所示。

图 7:需要 SSL 和客户证书
最后,需要对客户端进行配置,以从文件加载证书并提交给 Web 服务。
System.Security.Cryptography.X509Certificates.X509Certificate 类知道如何读取 X.509 证书。要加载证书并使其可以被 Web 服务使用,请读入证书,并将其添加到代理的客户证书集合中。
| static void Main(string[] args) { localhost.Sample svc = new localhost.Sample(); try { X509Certificate x509 = X509Certificate.CreateFromCertFile( @"c:\temp\secSample.cer"); svc.ClientCertificates.Add( x509 ); Console.WriteLine( svc.WhoAmI() ); } catch ( Exception ex ) { Console.WriteLine( ex.ToString() ); } finally { svc.Dispose(); } } |
正如所料,输出为:
作为以下用户运行 : SSEELY2\example
使用基本/简要身份验证或 X.509 验证用户身份时,您也可以使用访问控制列表 (ACL) 来确定那些用户可以访问目录。一种查看文件或目录的 ACL 的方法是使用 Windows 资源管理器。右键单击文件,然后单击“属性”。在“安全性”选项卡中,您可以添加或删除用户和用户组,也可以对这些用户操作文件的权限进行管理。