注意:本文假设您已经比较熟悉如何配合使用 SSL 和 IIS。简介 有一个一直让 Web 服务开发人员感到头疼的课题,那就是:如何使 IIS 和 ASP.NET Web 服务协同工作以提供安全性。现在,我们通过 IIS 来处理安全问题,并通过 ASP.NET 进行调节。ASP.NET 可以接受 IIS 提供的身份标识信息并使用该信息来了解调用者是谁,或者利用代码访问安全性在 Web 服务上执行特定操作。对于许多人而言,最大的问题是如何使 .NET应用程序利用内置的 IIS 安全保护功能。在不远的将来,WS-Security 将是您的更佳选择。在那一天到来之前,HTTP 级的安全保护将是我们许多人用来保证信息安全的方法。

图 1:IIS 管理控制台中的“安全性”选项卡

图 2:“安全通信”对话框
默认情况下“需要安全通道 (SSL)”复选框没有被选中,请选中该复选框以请求 SSL。SSL 支持 40 位和 128 位加密。加密使用的位数越多,破译和找出原始位就越困难。这就是为特定的 .asmx 文件或整个 Web 服务启用 SSL 所要做的全部工作。这样,只要 Web 服务器的证书不受威胁,所有 Web 服务客户端和 Web 服务本身都将是安全的。SSL 使用包含公钥的 X.509 证书,可能还包含一个私钥。如果私钥被外部用户知道,则使用公钥加密的通信就可能会被外部用户侦测到,从而变得不安全。| <configuration> <system.web> <authentication mode="Windows" /> <!-- 其他元素将放在此处 --> </system.web> </configuration> |

图 3:禁用匿名访问的“身份验证方法”对话框
“身份验证方法”对话框允许您配置用户访问虚拟目录或文件的方法。要通过 HTTP 信息头传递用户凭据,您可以使用基本或简要身份验证。基本和简要身份验证均不提供任何确保消息安全的机制。传递用户凭据的机制由 RFC 2617: HTTP Authentication: Basic and Digest Access Authentication定义。基本上,使用一个名为 Authorization 的 HTTP 信息头来传递用户名和密码。对于基本身份验证而言,用户名/密码组合是以明文的方式发送的。不过,也不全是这样。实际上,用户名和密码是使用简单明文形式的 base64 编码方法来发送的。如果您不熟悉 base64 编码,可以使用二进制数据并以文本形式提供这些数据。对数据进行编码时,不使用机密/密钥。如果选择使用基本身份验证,则只能接受通过 SSL 的凭据。这可以保护 Web 服务和调用者免受试图攻击通道以捕获有效凭据集的实体的威胁。| [WebMethod] public string WhoAmI() { return "正在作为用户运行: " + Thread.CurrentPrincipal.Identity.Name; } |
| 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(); } } |

图 4:无安全保护运行,因而也没有身份标识
如果您通过图 3 中的对话框关闭匿名访问,客户端将无法访问 Web 服务。相反,将显示以下错误消息:| svc.Credentials = System.Net.CredentialCache.DefaultCredentials; Console.WriteLine( svc.WhoAmI() ); |
| 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() ); |

图 5:“证书”对话框
您需要导出一个证书,以便可以被 Web 服务代理身份验证使用。要导出证书,请单击“导出”打开“证书导出向导”。在向导中,单击“下一步”接受所有默认选项,然后选择一个写入证书的文件名。在我的示例中,我将证书保存到 c:\temp\secSample.cer 中。单击“下一步”,然后单击“完成”。现在,我们需要将该证书与某个特定用户关联起来。
图 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(); } } |
| [WebMethod] [PrincipalPermissionAttribute(SecurityAction.Demand, Authenticated=true, Name=@"sseely2\Example", Role=@"sseely2\SampleGroup")] public string WhoAmI() { return "作为以下用户运行: " + Thread.CurrentPrincipal.Identity.Name; } |