结合使用 CardSpace 和 wsHttpBinding

此示例演示在 Web 服务中如何配置 wsHttpBinding 以使用 CardSpace。

提示

本主题的末尾介绍了此示例的设置过程和生成说明。

此示例定义了一个 ISecureCalculator 协定,用来说明如何使用由 CardSpace 表示的个人身份声明。CalculatorService 定义和实现了一个名为 ISecureCalculator 的服务协定,如下面的示例代码所示:

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ISecureCalculator
{
    [OperationContract]
    double Add(double n1, double n2);
    [OperationContract]
    double Subtract(double n1, double n2);
    [OperationContract]
    double Multiply(double n1, double n2);
    [OperationContract]
    double Divide(double n1, double n2);
    [OperationContract]
    string GetIdentity();
}

该服务配置为要求使用由 CardSpace 提供的 SAML 令牌。

GetIdentity 操作的服务实现会提取私人标识符 (PPID) 声明并在响应中返回它。PrivatePersonalIdentifier 是一个具有内置隐私功能的唯一常量,该隐私功能由令牌的颁发者生成。服务可以使用此标识符连同其他信息(如颁发者的签名和其他声明)来进行帐户查找和身份验证。PPID 因服务不同而异,即使选择的是同一个卡也是如此。

const string ppidClaimType = 
"https://schemas.xmlsoap.org/ws/2005/05/identity/claims/ privatepersonalidentifier"; 
public string GetIdentity()
{
 string identity=String.Empty;

 AuthorizationContext ctx = OperationContext.Current.ServiceSecurityContext.AuthorizationContext;

 foreach (ClaimSet claimSet in ctx.ClaimSets)
 {
    foreach (Claim claim in claimSet.FindClaims(ppidClaimType, null))
    {
        identity += claim.Resource as string; 
    }
 }

    return identity;
}

服务公开在配置文件 (Web.config) 中定义的单个终结点,配置文件需要来自请求者的 CardSpace,如下面的示例配置所示:

   <services>
      <service 
       name="Microsoft.ServiceModel.Samples.CalculatorService" 
       behaviorConfiguration="ServiceCredentials">
        <!-- This endpoint is exposed at the base address provided by host: https://localhost/servicemodelsamples/service.svc  -->
        <endpoint address=""
         binding="wsHttpBinding"
         bindingConfiguration="requireInfoCard"
         contract="Microsoft.ServiceModel.Samples.ISecureCalculator" >
          <identity>
            <certificateReference 
             findValue="545c3b8e97d99fd75c75eb52c6908320088b4f50" 
             x509FindType="FindByThumbprint" 
             storeLocation="LocalMachine" 
             storeName="My" />
          </identity>
        </endpoint>
        <!-- The mex endpoint is exposed at https://localhost/servicemodelsamples/service.svc/mex. -->
        <endpoint address="mex"
          binding="mexHttpBinding"
          contract="IMetadataExchange" />
      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="requireInfoCard">
          <security mode="Message">
            <message clientCredentialType="IssuedToken" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

服务还配置一个行为来指定服务证书,客户端使用该服务证书来对服务进行身份验证并保证发送给服务的消息的安全。

    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceCredentials">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceCredentials>
            <serviceCertificate
             findValue="545c3b8e97d99fd75c75eb52c6908320088b4f50"
             x509FindType="FindByThumbprint"
             storeLocation="LocalMachine"
             storeName="My" />
            <issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
          </serviceCredentials>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

客户端还配置为需要由 CardSpace 提供的 SAML 令牌,这会导致在首次向服务发出请求时启动 CardSpace 用户界面。用户可以选择要显示给服务的相应信息卡。在选择了信息卡之后,将使用表示身份的 SAML 令牌来确保请求的安全。针对 ISecureCalculator 协定的 GetIdentity 操作会提取在 SAML 令牌中提供的 PrivatePersonalIdentifer 声明并将其返回给调用方。

客户端使用由Service Metadata Utility Tool (Svcutil.exe) 生成的类型化 WCF 客户端类来与服务进行通信。该类型化 Windows Communication Foundation (WCF) 客户端类包含在 GeneratedProxy.cs 文件中。

客户端的配置还可以使用Service Metadata Utility Tool (Svcutil.exe) 来生成。Service Metadata Utility Tool (Svcutil.exe) 根据服务所发布的元数据来创建客户端终结点配置。在此示例中,客户端配置是从服务配置开始手动创建的。

对于客户端,必须将 clientCredentialType 设置为 IssuedToken,并将 certificateReference 配置为允许 CardSpace 对服务进行身份验证,如下面的示例配置中所示:

    <client>
      <endpoint
       address="https://localhost/ServiceModelSamples/service.svc/"
       bindingConfiguration="requireInfoCard" 
       binding="wsHttpBinding"
       contract="Microsoft.ServiceModel.Samples.ISecureCalculator"
       behaviorConfiguration="ClientCredentials">
        <identity>
          <certificateReference
           findValue="545c3b8e97d99fd75c75eb52c6908320088b4f50" 
           x509FindType="FindByThumbprint"
           storeLocation="CurrentUser" 
           storeName="TrustedPeople" />
        </identity>
      </endpoint>
    </client>

    <bindings>
      <wsHttpBinding>
        <binding name="requireInfoCard">
          <security mode="Message">
            <message clientCredentialType="IssuedToken" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

除了在终结点中提供服务证书以外,客户端还必须指定它所信任的服务的证书。这是通过以下方法来完成的:定义一个行为来引用客户端所信任的证书存储区中的证书。

    <behaviors>
      <endpointBehaviors>
        <behavior name="ClientCredentials" 
         includeExceptionDetailInFaults="true">
          <clientCredentials>
            <serviceCertificate>
              <defaultCertificate
               findValue="545c3b8e97d99fd75c75eb52c6908320088b4f50"
               x509FindType="FindByThumbprint"
               storeLocation="CurrentUser"
               storeName="TrustedPeople" />
              <!-- 
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate 
            is in the user's Trusted People store, then it will be 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 certificate 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. 
            -->
              <authentication
               revocationMode="NoCheck"
               certificateValidationMode="PeerOrChainTrust" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

在运行该客户端并按 Enter 时,客户端会调用 GetIdentity 操作,而且会启动 CardSpace 用户界面:

  • 从 CardSpace 中选择一个已有的卡,或者创建一个新卡。
  • 通过单击**“发送”**来提交该卡。

CardSpace 中的声明会以 CardSpace 的 SAML 令牌序列化形式发送给服务。服务的 GetIdentity 操作会使用从 SAML 令牌提取的声明进行响应。客户端随后会调用服务的计算器操作,响应将显示在控制台窗口中。

Identity - (Private Personal ID) =  LGGjXshcVQE1kFMnxccopDBGvYu6gVs2Aexx+4bMlbk=

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.

设置、生成和运行示例

  1. 请确保已经执行了 Windows Communication Foundation 示例的一次性安装过程

  2. 若要用单一计算机配置或跨计算机配置来运行示例,请按照下列说明进行操作。特别是,从示例安装目录下特定于语言的目录中运行 Setup.bat。

    提示

    Setup.bat 批处理文件设计为通过 Windows SDK 命令提示运行。这要求 MSSDK 环境变量指向 SDK 的安装目录。将在 Windows SDK 命令提示中自动设置此环境变量。对于 Windows Vista,请确保 IIS 7.0 中安装了 IIS 6.0 兼容性支持功能。

  3. 若要生成 C# 或 Visual Basic 版本的解决方案,请按照生成 Windows Communication Foundation 示例中的说明进行操作。

  4. 在完成示例后,从示例安装目录下特定于语言的目录中运行 Cleanup.bat。

在同一计算机上运行示例

  1. 将 Simple\SampleResources\Fabrikam-Contoso.pfx 证书导入 LocalMachine/My(个人)证书存储区中。此证书的密码是 xyz。

    提示

    请导入 Fabrikam-Contoso.pfx 文件,而不是 Fabrikam-Contoso-Public.cer 文件。

  2. 从 Simple 目录下特定于语言的目录中运行 Setup.bat。这会将 Fabrikam-Contoso-Public.cer 证书安装到 CurrentUser/TrustedPeople 证书存储区中,供客户端使用。这还会为 IIS 承载的 Web 服务授予读取在上一步中安装的 Fabrikam 证书的私钥的权限。

    提示

    在 Windows Vista 上,手动导入证书,然后运行 Setup.bat。如果失败,则可能会导致“密钥集不存在”错误。

    提示

    请确保在完成 CardSpace 示例后通过运行 Cleanup.bat 来移除证书。其他 CardSpace 示例使用相同的证书。Setup.bat 批处理文件设计为通过 Windows SDK 命令提示运行。这要求 MSSDK 环境变量指向 SDK 的安装目录。将在 Windows SDK 命令提示中自动设置此环境变量。

  3. 生成 Visual Studio 解决方案示例文件 CardSpace.sln,该文件位于 Simple 文件夹下特定于语言的文件夹中。

  4. 若要验证服务是否在运行,请在 Web 浏览器中打开以下地址:https://localhost/servicemodelsamples/service.svc,该地址将显示服务的摘要。

  5. 从 Simple\<CS,VB>\client\bin 启动 client.exe。

  6. 如果客户端与服务无法进行通信,请参见疑难解答指南

跨计算机运行示例

  1. 在承载 Web 服务的服务器上:

    1. 如果服务器上尚且不存在示例源目录,请将 TechnologySamples\Basic\Binding\WS\CardSpace\Simple 目录复制到服务器上。

    2. 将 Simple\SampleResources\Fabrikam-Contoso.pfx 证书导入 LocalMachine/My(个人)证书存储区中。此证书的密码是 xyz。

      提示

      请导入 Fabrikam-Contoso.pfx 文件,而不是 Fabrikam-Contoso-Public.cer 文件。

    3. 从 Simple 目录下特定于语言的目录中运行 Setup.bat。

      提示

      Setup.bat 会将客户端所需的证书安装到 CurrentUser/TrustedPeople 中,并将徽标图像复制到 ServiceModelSamples 虚拟目录中。为了避免此操作,请安装服务的证书,而不是运行 Setup.bat。

    4. 生成 Simple\<CS,VB>\service\service.csproj 项目。

    5. 若要验证服务是否在运行,请在 Web 浏览器中打开以下地址:https://localhost/servicemodelsamples/service.svc,该地址将显示服务的摘要。

      提示

      在服务器上完成示例的运行之后,从 Simple 文件夹下特定于语言的目录中运行 Cleanup.bat。

  2. 在承载客户端的计算机上:

    1. 如果计算机上尚且不存在示例源目录,请将 TechnologySamples\Basic\Binding\WS\CardSpace\Simple 目录复制到计算机上。
    2. 从 Simple 目录下特定于语言的目录中运行 Setup.bat。不必安装包含在 Fabrikam-Contoso.pfx 中的服务证书。
    3. 生成 Simple\<CS,VB>\client\client.csproj 项目。
    4. 在 client\bin\client.exe.config 文件中,更改 <endpoint address=" https://localhost/ServiceModelSamples/service.svc" .../> 中的地址,使其与 Web 服务的新地址相匹配。
  3. 运行 client\bin\client.exe。

    提示

    在完成示例的运行之后,运行 Cleanup.bat。

  4. 如果客户端与服务无法进行通信,请参见疑难解答指南

运行示例后进行清除

  1. 从示例安装目录下特定于语言的目录中运行 Cleanup.bat。

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.