此示例演示如何实现一个应用程序,该应用程序使用 WS-Security 进行客户端的用户名身份验证,并使用服务器的 X.509v3 证书进行服务器身份验证。 客户端和服务器之间的所有应用程序消息都经过签名和加密。 默认情况下,客户端提供的用户名和密码用于登录到有效的 Windows 帐户。 此示例基于 WSHttpBinding。 此示例由 Internet 信息服务(IIS)托管的客户端控制台程序(Client.exe)和服务库(Service.dll)组成。 该服务实现定义请求-回复通信模式的协定。
注释
本示例的设置过程和生成说明位于本主题末尾。
此示例还演示了:
到 Windows 帐户的默认映射,以便可以执行其他授权。
如何从服务代码访问调用方的身份信息。
该服务公开一个终结点,用于与服务通信,该服务使用配置文件 Web.config定义。终结点由地址、绑定和协定组成。 绑定使用标准 <wsHttpBinding> 进行配置,该标准默认使用消息安全性。 此示例将标准 <wsHttpBinding> 设置为使用客户端用户名身份验证。 该行为指定用户凭据用于服务身份验证。 服务器证书包含的主题名称值必须与 > 中 属性的值相同。
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding" />
</protocolMapping>
<bindings>
<wsHttpBinding>
<!--
This configuration defines the security mode as Message and
the clientCredentialType as Username.
By default, Username authentication attempts to authenticate the provided
username as a Windows computer or domain account.
-->
<binding>
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true.-->
<behaviors>
<serviceBehaviors>
<behavior>
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by the service to authenticate itself to the client and to provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCredentials>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
客户端终结点配置由服务终结点、绑定和协定的绝对地址组成。 该客户端绑定是使用相应的 securityMode
和 authenticationMode
配置的。 在跨计算机方案中运行时,必须相应地更改服务终结点地址。
<system.serviceModel>
<client>
<endpoint address="http://localhost/servicemodelsamples/service.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding1"
behaviorConfiguration="ClientCredentialsBehavior"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</client>
<bindings>
<wsHttpBinding>
<!--
This configuration defines the security mode as Message and
the clientCredentialType as Username.
-->
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true.-->
<behaviors>
<endpointBehaviors>
<behavior name="ClientCredentialsBehavior">
<!--
Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
is in the user's Trusted People store, then it is trusted without performing a
validation of the certificate's issuer chain. This setting is used here for convenience so that the
sample can be run without having to have certificates issued by a certification authority (CA).
This setting is less secure than the default, ChainTrust. The security implications of this
setting should be carefully considered before using PeerOrChainTrust in production code.
-->
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
客户端实现设置要使用的用户名和密码。
// Create a client.
CalculatorClient client = new CalculatorClient();
// Configure client with valid computer or domain account (username,password).
client.ClientCredentials.UserName.UserName = username;
client.ClientCredentials.UserName.Password = password.ToString();
// Call GetCallerIdentity service operation.
Console.WriteLine(client.GetCallerIdentity());
...
//Closing the client gracefully closes the connection and cleans up resources.
client.Close();
运行示例时,操作请求和响应将显示在客户端控制台窗口中。 在客户端窗口中按 Enter 关闭客户端。
MyMachine\TestAccount
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.
使用与 MessageSecurity 示例随附的 Setup.bat 批处理文件,您可以配置服务器,添加相关证书,以运行需要基于证书安全性的服务器托管应用程序。 批处理文件可以在两种模式下运行。 若要在单计算机模式下运行批处理文件,请在命令行中键入 setup.bat
。 在服务模式类型 setup.bat service
中运行它。 在跨计算机运行示例时,请使用此模式。 有关详细信息,请参阅本主题末尾的设置过程。
下面简要概述了批处理文件的不同部分。
创建服务器证书
Setup.bat 批处理文件中的以下行创建要使用的服务器证书。
echo ************ echo Server cert setup starting echo %SERVER_NAME% echo ************ echo making server cert echo ************ makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
%SERVER_NAME% 变量指定服务器名称。 证书存储在 LocalMachine 存储中。 如果 Setup.bat 批处理文件是使用服务参数(如
setup.bat service
)运行的,则 %SERVER_NAME% 包含计算机的完全限定域名。 否则,它默认为 localhost。将服务器证书安装到客户端的受信任证书存储中
以下行将服务器证书复制到客户端的受信任人员库中。 此步骤是必需的,因为 Makecert.exe 生成的证书不受客户端系统隐式信任。 如果已有一个证书,该证书已植根于客户端受信任的根证书(例如Microsoft颁发的证书),则不需要使用服务器证书填充客户端证书存储区。
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
授予对证书私钥的权限
Setup.bat 批处理文件中的以下行可以让 ASP.NET 辅助进程帐户访问 LocalMachine 存储区中存储的服务器证书。
echo ************ echo setting privileges on server certificates echo ************ for /F "delims=" %%i in ('"%ProgramFiles%\ServiceModelSampleTools\FindPrivateKey.exe" My LocalMachine -n CN^=%SERVER_NAME% -a') do set PRIVATE_KEY_FILE=%%i set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE (ver | findstr /C:"5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R iisreset
注释
如果你使用的是非美国英语版的 Windows,必须编辑 Setup.bat 文件,并将
NT AUTHORITY\NETWORK SERVICE
帐户名称替换为等效的区域账户名。
设置、生成和运行示例
确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。
若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。
在同一计算机上运行示例
确保路径包括 Makecert.exe 和 FindPrivateKey.exe 所在的文件夹。
在使用管理员权限打开的 Visual Studio 开发人员命令提示符中,运行示例安装文件夹中的 Setup.bat。 这会安装运行示例所需的所有证书。
注释
Setup.bat 批处理文件旨在从 Visual Studio 的开发人员命令提示符运行。 它要求路径环境变量指向安装 SDK 的目录。 此环境变量在 Visual Studio 开发人员命令提示符内自动设置。
输入地址
http://localhost/servicemodelsamples/service.svc
,使用浏览器验证对服务的访问。从 \client\bin 启动 Client.exe。 客户端活动显示在客户端控制台应用程序中。
跨计算机运行示例
在服务计算机上创建目录。 使用 Internet Information Services 管理工具为此目录创建名为 servicemodelsamples 的虚拟应用程序。
将服务程序文件从 \inetpub\wwwroot\servicemodelsamples 复制到服务计算机上的虚拟目录。 确保复制 \bin 子目录中的文件。 此外,将 Setup.bat 和 Cleanup.bat 文件复制到服务计算机。
在客户端计算机上为客户端二进制文件创建目录。
将客户端程序文件复制到客户端计算机上的客户端目录。 此外,将 Setup.bat、Cleanup.bat和 ImportServiceCert.bat 文件复制到客户端。
在服务器上,使用管理员权限在 Visual Studio 的开发人员命令提示符下运行
setup.bat service
。 使用setup.bat
参数运行service
,则使用计算机的完全限定域名创建一个服务证书,并将此服务证书导出到名为 Service.cer 的文件中。编辑 Web.config 以反映新的证书名称(在 serviceCertificate 元素的 findValue 属性中),该名称与计算机的完全限定域名相同
.
将Service.cer文件从服务目录复制到客户端计算机上的客户端目录。
在客户端计算机上的 Client.exe.config 文件中,更改终结点的地址值以匹配服务的新地址。
在客户端上,使用管理员权限打开的 Visual Studio 开发人员命令提示符中运行 ImportServiceCert.bat。 这会将服务证书从 Service.cer 文件导入 CurrentUser - TrustedPeople 存储中。
在客户端计算机上,从命令提示符启动 Client.exe。 如果客户端和服务无法通信,请参阅 WCF 示例 故障排除提示。
运行示例后进行清理
运行完示例后,在示例文件夹中运行 Cleanup.bat。
注释
在跨计算机运行此示例时,此脚本不会删除客户端上的服务证书。 如果您运行了在不同计算机上使用证书的 Windows Communication Foundation (WCF) 示例,请确保清除已安装在当前用户 - TrustedPeople 存储库中的服务证书。 为此,请使用以下命令:
certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name>
例如:certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com
。