服务标识示例

此服务标识示例演示如何设置服务的标识。 在设计时,客户端可以使用服务的元数据检索标识,然后在运行时客户端可以对服务的标识进行身份验证。 服务标识的概念是允许客户端在调用任何作之前对服务进行身份验证,从而保护客户端免受未经身份验证的调用。 在安全连接上,服务在允许客户端访问之前还会对客户端的凭据进行身份验证,但这不是此示例的重点。 请参阅 客户端 中显示服务器身份验证的示例。

注释

本示例的设置过程和生成说明位于本主题末尾。

此示例演示了以下功能:

  • 如何在服务的不同终结点上设置不同类型的标识。 每种标识类型都具有不同的功能。 要使用的标识类型取决于终结点绑定上使用的安全凭据的类型。

  • 可以在配置中以声明方式设置标识,也可以在代码中以强制方式设置标识。 通常,对于客户端和服务,应使用配置来设置标识。

  • 如何在客户端上设置自定义标识。 自定义标识通常是对现有类型的标识的自定义,使客户端能够在调用服务之前检查服务凭据中提供的其他声明信息,以做出授权决策。

    注释

    此示例检查名为 identity.com 的特定证书的标识以及此证书中包含的 RSA 密钥。 在客户端上的配置中使用证书和 RSA 标识类型时,获取这些值的一种简单方法是检查 WSDL,了解序列化这些值的服务。

下面的示例代码演示如何使用 WSHttpBinding 向证书的域名服务器 (DNS) 配置服务终结点的标识。

//Create a service endpoint and set its identity to the certificate's DNS
WSHttpBinding wsAnonbinding = new WSHttpBinding (SecurityMode.Message);
// Client are Anonymous to the service
wsAnonbinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
WServiceEndpoint ep = serviceHost.AddServiceEndpoint(typeof(ICalculator),wsAnonbinding, String.Empty);
EndpointAddress epa = new EndpointAddress(dnsrelativeAddress,EndpointIdentity.CreateDnsIdentity("identity.com"));
ep.Address = epa;

还可以在 App.config 文件中的配置中指定标识。 以下示例演示如何为服务终结点设置 UPN(用户主体名称)标识。

<endpoint address="upnidentity"
        behaviorConfiguration=""
        binding="wsHttpBinding"
        bindingConfiguration="WSHttpBinding_Windows"
        name="WSHttpBinding_ICalculator_Windows"
        contract="Microsoft.ServiceModel.Samples.ICalculator">
  <!-- Set the UPN identity for this endpoint -->
  <identity>
      <userPrincipalName value="host\myservice.com" />
  </identity >
</endpoint>

可以通过派生自 EndpointIdentity 类和 IdentityVerifier 类在客户端上设置自定义标识。 从概念上讲,IdentityVerifier 类可以被视为服务的 AuthorizationManager 类的客户端等效物。 下面的代码示例演示了 OrgEndpointIdentity 的实现,它用于存储组织名称,以便与服务器证书的主题名称相匹配。 对组织名称的授权检查发生在 CheckAccess 类的 CustomIdentityVerifier 方法中。

// This custom EndpointIdentity stores an organization name
public class OrgEndpointIdentity : EndpointIdentity
{
    private string orgClaim;
    public OrgEndpointIdentity(string orgName)
    {
        orgClaim = orgName;
    }
    public string OrganizationClaim
    {
        get { return orgClaim; }
        set { orgClaim = value; }
    }
}

//This custom IdentityVerifier uses the supplied OrgEndpointIdentity to
//check that X.509 certificate's distinguished name claim contains
//the organization name e.g. the string value "O=Contoso"
class CustomIdentityVerifier : IdentityVerifier
{
    public override bool CheckAccess(EndpointIdentity identity, AuthorizationContext authContext)
    {
        bool returnvalue = false;
        foreach (ClaimSet claimset in authContext.ClaimSets)
        {
            foreach (Claim claim in claimset)
            {
                if (claim.ClaimType == "http://schemas.microsoft.com/ws/2005/05/identity/claims/x500distinguishedname")
                {
                    X500DistinguishedName name = (X500DistinguishedName)claim.Resource;
                    if (name.Name.Contains(((OrgEndpointIdentity)identity).OrganizationClaim))
                    {
                        Console.WriteLine("Claim Type: {0}",claim.ClaimType);
                        Console.WriteLine("Right: {0}", claim.Right);
                        Console.WriteLine("Resource: {0}",claim.Resource);
                        Console.WriteLine();
                        returnvalue = true;
                    }
                }
            }
        }
        return returnvalue;
    }
}

此示例使用名为 identity.com 的证书,该证书位于特定于语言的标识解决方案文件夹中。

设置、生成和运行示例

  1. 确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。

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

  3. 要使用单机配置或跨计算机配置运行示例,请按照运行 Windows Communication Foundation 示例中的说明进行操作。

在同一计算机上运行示例

  1. 在 Windows XP 或 Windows Vista 上,使用 MMC 管理单元工具将 Identity 解决方案文件夹中的 Identity.pfx 证书文件导入 LocalMachine/My(个人)证书存储中。 此文件受密码保护。 在导入过程中,系统会要求输入密码。 键入 xyz 密码框。 有关详细信息,请参阅如何:使用 MMC 管理单元查看证书主题。 完成此作后,使用管理员权限在 Visual Studio 的开发人员命令提示符中运行 Setup.bat,该命令会将此证书复制到 CurrentUser/Trusted People 存储,以便在客户端上使用。

  2. 在 Windows Server 2003 上,使用管理员权限从 Visual Studio 命令提示符内的示例安装文件夹运行 Setup.bat。 这会安装运行示例所需的所有证书。

    注释

    Setup.bat 批处理文件设计为通过 Visual Studio 命令提示符运行。 在 Visual Studio 命令提示中设置的 PATH 环境变量指向包含 Setup.bat 脚本所需的可执行文件的目录。 完成示例后,请确保通过运行 Cleanup.bat 来删除证书。 其他安全示例使用相同的证书。

  3. 从 \service\bin 目录启动 Service.exe。 确保服务指示其已准备就绪,并显示一个提示:按下<Enter>键来终止服务。

  4. 从 \client\bin 目录启动 Client.exe,或在 Visual Studio 中按 F5 以生成并运行。 客户端活动显示在客户端控制台应用程序中。

  5. 如果客户端和服务无法通信,请参阅 WCF 示例 故障排除提示。

跨计算机运行示例

  1. 在生成示例的客户端部分之前,请务必更改方法中Client.cs文件中 CallServiceCustomClientIdentity 服务终结点地址的值。 然后生成示例。

  2. 在服务计算机上创建目录。

  3. 将服务程序文件从 service\bin 复制到服务计算机上的目录。 此外,将 Setup.bat 和 Cleanup.bat 文件复制到服务计算机。

  4. 在客户端计算机上为客户端二进制文件创建目录。

  5. 将客户端程序文件复制到客户端计算机上的客户端目录。 此外,将 Setup.bat、Cleanup.bat和 ImportServiceCert.bat 文件复制到客户端。

  6. 在服务中,使用管理员权限在 Visual Studio 的开发人员命令提示符下运行 setup.bat service 。 使用 setup.bat 参数运行 service,则使用计算机的完全限定域名创建一个服务证书,并将此服务证书导出到名为 Service.cer 的文件中。

  7. 将Service.cer文件从服务目录复制到客户端计算机上的客户端目录。

  8. 在客户端计算机上的 Client.exe.config 文件中,更改终结点的地址值以匹配服务的新地址。 有多个实例需要更改。

  9. 在客户端上,使用管理员权限打开的 Visual Studio 开发人员命令提示符中运行 ImportServiceCert.bat。 这会将服务证书从 Service.cer 文件导入 CurrentUser - TrustedPeople 存储中。

  10. 在服务计算机上,从命令提示符启动 Service.exe。

  11. 在客户端计算机上,在命令提示符下启动 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