在应用之间共享证书Share certificates between apps

要求用户名和密码组合以上的安全身份认证的通用 Windows 平台 (UWP) 应用可以使用证书进行身份验证。Universal Windows Platform (UWP) apps that require secure authentication beyond a user Id and password combination can use certificates for authentication. 对用户进行身份验证时,证书身份验证将提供高级别的信任。Certificate authentication provides a high level of trust when authenticating a user. 在某些情况下,一组服务将要针对多个应用对用户进行身份验证。In some cases, a group of services will want to authenticate a user for multiple apps. 本文介绍了如何使用同一个证书对多个应用进行身份验证,以及如何提供方便代码,用户可使用此代码导入提供的证书以访问安全的 Web 服务。This article shows how you can authenticate multiple apps using the same certificate, and how you can provide convenient code for a user to import a certificate that was provided to access secured web services.

应用可使用证书对 Web 服务进行身份验证,并且多个应用可使用来自证书存储的单个证书对相同的用户进行身份验证。Apps can authenticate to a web service using a certificate, and multiple apps can use a single certificate from the certificate store to authenticate the same user. 如果存储中不存在证书,可将代码添加到应用以从 PFX 文件导入证书。If a certificate does not exist in the store, you can add code to your app to import a certificate from a PFX file.

启用 Microsoft Internet 信息服务 (IIS) 和客户端证书映射Enable Microsoft Internet Information Services (IIS) and client certificate mapping

本文以 Microsoft Internet 信息服务 (IIS) 为例。This article uses Microsoft Internet Information Services (IIS) for example purposes. 默认情况下不启用 IIS。IIS is not enabled by default. 可通过使用控制面板来启用 IIS。You can enable IIS by using the Control Panel.

  1. 打开“控制面板”,选择“程序”****。Open the Control Panel and select Programs.
  2. 选择 "打开或关闭 Windows 功能"Select Turn Windows features on or off.
  3. 展开“Internet 信息服务”****,然后展开“万维网服务”****。Expand Internet Information Services and then expand World Wide Web Services. 展开“应用程序开发功能”**** 并选择“ASP.NET 3.5”**** 和“ASP.NET 4.5”****。Expand Application Development Features and select ASP.NET 3.5 and ASP.NET 4.5. 做出这些选择将自动启用 Internet 信息服务Making these selections will automatically enable Internet Information Services.
  4. 单击“确定”应用更改。Click OK to apply the changes.

创建并发布安全的 Web 服务Create and publish a secured web service

  1. 作为管理员运行 Microsoft Visual Studio 并从起始页选择“新建项目”****。Run Microsoft Visual Studio as administrator and select New Project from the start page. 将 Web 服务发布到 IIS 服务器需要管理员访问权限。Administrator access is required to publish a web service to an IIS server. 在“新建项目”对话框中,将框架更改为“.NET Framework 3.5”****。In the New Project dialog, change the framework to .NET Framework 3.5. 选择 " visual c # - > Web - > visual Studio - > ASP.NET Web 服务应用程序"。Select Visual C# -> Web -> Visual Studio -> ASP.NET Web Service Application. 将应用程序命名为“FirstContosoBank”。Name the application "FirstContosoBank". 单击“确定”以创建该项目 。Click OK to create the project.

  2. Service1.asmx.cs 文件中,用以下“登录”方法替换 HelloWorld Web 方法。In the Service1.asmx.cs file, replace the default HelloWorld web method with the following "Login" method.

            [WebMethod]
            public string Login()
            {
                // Verify certificate with CA
                var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(
                    this.Context.Request.ClientCertificate.Certificate);
                bool test = cert.Verify();
                return test.ToString();
            }
    
  3. 保存 Service1.asmx.cs 文件。Save the Service1.asmx.cs file.

  4. 在“解决方案资源管理器”**** 中,右键单击“FirstContosoBank”应用并选择“发布”****。In the Solution Explorer, right-click the "FirstContosoBank" app and select Publish.

  5. 在“发布 Web”**** 对话框中,创建新的配置文件并将其命名为“ContosoProfile”。In the Publish Web dialog, create a new profile and name it "ContosoProfile". 单击“下一步”。Click Next.

  6. 在下一个页面上,为你的 IIS 服务器输入服务器名并指定“默认 Web 站点/FirstContosoBank”的站点名。On the next page, enter the server name for your IIS server, and specify a site name of "Default Web Site/FirstContosoBank". 单击“发布”**** 以发布你的 Web 服务。Click Publish to publish your web service.

配置你的 Web 服务以使用客户端认证身份验证。Configure your web service to use client certificate authentication

  1. 运行“Internet 信息服务 (IIS) 管理器”****。Run the Internet Information Services (IIS) Manager.
  2. 展开你的 IIS 服务器的站点。Expand the sites for your IIS server. 在“默认 Web 站点”**** 下,选择新的“FirstContosoBank”Web 服务。Under the Default Web Site, select the new "FirstContosoBank" web service. 在“操作”**** 部分中,选择“高级设置...”****。In the Actions section, select Advanced Settings....
  3. 将“应用程序池”**** 设置为“.NET v2.0”**** 并单击“确定”****。Set the Application Pool to .NET v2.0 and click OK.
  4. 在“Internet 信息服务 (IIS) 管理器”**** 中,选择你的 IIS 服务器,然后双击“服务器证书”****。In the Internet Information Services (IIS) Manager, select your IIS server and then double-click Server Certificates. 操作部分中,选择创建自签名证书…。输入“ContosoBank”作为证书的易记名称,然后单击确定In the Actions section, select Create Self-Signed Certificate.... Enter "ContosoBank" as the friendly name for the certificate and click OK. 这将创建一个新的证书供 IIS 服务器以“<server-name>.<domain-name>”格式使用。This will create a new certificate for use by the IIS server in the form of "<server-name>.<domain-name>".
  5. 在“Internet 信息服务 (IIS) 管理器”**** 中,选择默认网站。In the Internet Information Services (IIS) Manager, select the default web site. 操作部分中,选择绑定,然后单击添加...。选择“https”作为类型,将端口设置为“443”,然后输入 IIS 服务器的完整主机名(“<server-name>.<domain-name>”)。In the Actions section, select Binding and then click Add.... Select "https" as the type, set the port to "443", and enter the full host name for your IIS server ("<server-name>.<domain-name>"). 将 SSL 证书设置为“ContosoBank”。Set the SSL certificate to "ContosoBank". 单击" 确定"。Click OK. 单击“站点绑定”**** 窗口中的“关闭”****。Click Close in the Site Bindings window.
  6. 在“Internet 信息服务 (IIS) 管理器”**** 中,选择“FirstContosoBank”Web 服务。In the Internet Information Services (IIS) Manager, select the "FirstContosoBank" web service. 双击“SSL 设置”****。Double-click SSL Settings. 选中“要求 SSL”****。Check Require SSL. 在“客户端证书”**** 下,选择“要求”****。Under Client certificates, select Require. 在“操作”**** 部分中,单击“应用”****。In the Actions section, click Apply.
  7. 你可以通过打开 Web 浏览器并输入以下 Web 地址来验证 Web 服务是否正确配置:“https://<server-name>.<domain-name>/FirstContosoBank/Service1.asmx”。You can verify that the web service is configured correctly by opening your web browser and entering the following web address: "https://<server-name>.<domain-name>/FirstContosoBank/Service1.asmx". 例如“https://myserver.example.com/FirstContosoBank/Service1.asmx”。For example, "https://myserver.example.com/FirstContosoBank/Service1.asmx". 如果 Web 服务已正确配置,系统将提示你选择一个客户端证书以访问该 Web 服务。If your web service is configured correctly, you will be prompted to select a client certificate in order to access the web service.

你可以重复之前的步骤以创建多个可使用相同客户端证书访问的 Web 服务。You can repeat the previous steps to create multiple web services that can be accessed using the same client certificate.

创建使用证书身份验证的 UWP 应用Create a UWP app that uses certificate authentication

现在你已拥有一个或多个安全 Web 服务,应用可使用证书来验证这些 Web 服务。Now that you have one or more secured web services, your apps can use certificates to authenticate to those web services. 在使用 HttpClient 对象发出对经过身份验证的 Web 服务的请求时,初始请求将不包含客户端证书。When you make a request to an authenticated web service using the HttpClient object, the initial request will not contain a client certificate. 经过身份验证的 Web 服务将以对客户端身份验证的请求进行响应。The authenticated web service will respond with a request for client authentication. 当此情况发生时,Windows 客户端将自动查询证书存储以获取可用的客户端证书。When this occurs, the Windows client will automatically query the certificate store for available client certificates. 用户可以从这些证书中选择以对 Web 服务进行身份验证。Your user can select from these certificates to authenticate to the web service. 一些证书受密码保护,所以你将需要向用户提供输入证书密码的方法。Some certificates are password protected, so you will need to provide the user with a way to input the password for a certificate.

如果没有可用的客户端证书,则用户将需要将证书添加到证书存储。If there are no client certificates available, then the user will need to add a certificate to the certificate store. 可将代码包括在 Windows 应用商店应用中,此应用使用户能够选择包含客户端证书的 PFX 文件,然后将该证书导入到客户端证书存储中。You can include code in your app that enables a user to select a PFX file that contains a client certificate and then import that certificate into the client certificate store.

提示   你可以使用 makecert.exe 来创建用于本快速入门的 PFX 文件。Tip  You can use makecert.exe to create a PFX file to use with this quickstart. 有关使用 makecert.exe 的信息,请参阅 MakeCertFor information on using makecert.exe, see MakeCert.

 

  1. 打开 Visual Studio,然后在起始页创建新的项目。Open Visual Studio and create a new project from the start page. 将此新项目命名为“FirstContosoBankApp”。Name the new project "FirstContosoBankApp". 单击“确定”以创建新项目****。Click OK to create the new project.

  2. 在 MainPage.xaml 文件中,将以下 XAML 添加到默认 Grid 元素中。In the MainPage.xaml file, add the following XAML to the default Grid element. 此 XAML 包括一个用于浏览要导入的 PFX 文件的按钮、一个用于输入受密码保护的 PFX 文件的密码的文本框、一个用于导入选中的 PFX 文件的按钮、一个用于登录安全 Web 服务的按钮以及一个用于显示当前操作状况的文本块。This XAML includes a button to browse for a PFX file to import, a text box to enter a password for a password-protected PFX file, a button to import a selected PFX file, a button to log in to the secured web service, and a text block to display the status of the current action.

    <Button x:Name="Import" Content="Import Certificate (PFX file)" HorizontalAlignment="Left" Margin="352,305,0,0" VerticalAlignment="Top" Height="77" Width="260" Click="Import_Click" FontSize="16"/>
    <Button x:Name="Login" Content="Login" HorizontalAlignment="Left" Margin="611,305,0,0" VerticalAlignment="Top" Height="75" Width="240" Click="Login_Click" FontSize="16"/>
    <TextBlock x:Name="Result" HorizontalAlignment="Left" Margin="355,398,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="153" Width="560"/>
    <PasswordBox x:Name="PfxPassword" HorizontalAlignment="Left" Margin="483,271,0,0" VerticalAlignment="Top" Width="229"/>
    <TextBlock HorizontalAlignment="Left" Margin="355,271,0,0" TextWrapping="Wrap" Text="PFX password" VerticalAlignment="Top" FontSize="18" Height="32" Width="123"/>
    <Button x:Name="Browse" Content="Browse for PFX file" HorizontalAlignment="Left" Margin="352,189,0,0" VerticalAlignment="Top" Click="Browse_Click" Width="499" Height="68" FontSize="16"/>
    <TextBlock HorizontalAlignment="Left" Margin="717,271,0,0" TextWrapping="Wrap" Text="(Optional)" VerticalAlignment="Top" Height="32" Width="83" FontSize="16"/>
    
  3. 保存 MainPage.xaml 文件。Save the MainPage.xaml file.

  4. 在 MainPage.xaml.cs 文件中,添加以下 using 语句。In the MainPage.xaml.cs file, add the following using statements.

    using Windows.Web.Http;
    using System.Text;
    using Windows.Security.Cryptography.Certificates;
    using Windows.Storage.Pickers;
    using Windows.Storage;
    using Windows.Storage.Streams;
    
  5. 在 MainPage.xaml.cs 文件中,将以下变量添加到 MainPage 类中。In the MainPage.xaml.cs file, add the following variables to the MainPage class. 它们指定“FirstContosoBank”Web 服务的安全“登录”方法的地址以及承载要导入到证书存储中的 PFX 证书的全局变量。They specify the address for the secured "Login" method of your "FirstContosoBank" web service, and a global variable that holds a PFX certificate to import into the certificate store. 将 <server-name> 更新为 Microsoft Internet Information Server (IIS) 服务器的完全限定的服务器名称。Update the <server-name> to the fully-qualified server name for your Microsoft Internet Information Server (IIS) server.

    private Uri requestUri = new Uri("https://<server-name>/FirstContosoBank/Service1.asmx?op=Login");
    private string pfxCert = null;
    
  6. 在 MainPage.xaml.cs 文件中,添加登录按钮的以下单击处理程序和访问安全 Web 服务的方法。In the MainPage.xaml.cs file, add the following click handler for the login button and method to access the secured web service.

    private void Login_Click(object sender, RoutedEventArgs e)
    {
        MakeHttpsCall();
    }
    
    private async void MakeHttpsCall()
    {
    
        StringBuilder result = new StringBuilder("Login ");
        HttpResponseMessage response;
        try
        {
            Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
            response = await httpClient.GetAsync(requestUri);
            if (response.StatusCode == HttpStatusCode.Ok)
            {
                result.Append("successful");
            }
            else
            {
                result = result.Append("failed with ");
                result = result.Append(response.StatusCode);
            }
        }
        catch (Exception ex)
        {
            result = result.Append("failed with ");
            result = result.Append(ex.Message);
        }
    
        Result.Text = result.ToString();
    }
    
  7. 在 MainPage.xaml.cs 文件中,添加以下用于浏览 PFX 文件的按钮和用于将选中的 PFX 文件导入到证书存储中的按钮的单击处理程序。In the MainPage.xaml.cs file, add the following click handlers for the button to browse for a PFX file and the button to import a selected PFX file into the certificate store.

    private async void Import_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            Result.Text = "Importing selected certificate into user certificate store....";
            await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync(
                pfxCert,
                PfxPassword.Password,
                ExportOption.Exportable,
                KeyProtectionLevel.NoConsent,
                InstallOptions.DeleteExpired,
                "Import Pfx");
    
            Result.Text = "Certificate import succeded";
        }
        catch (Exception ex)
        {
            Result.Text = "Certificate import failed with " + ex.Message;
        }
    }
    
    private async void Browse_Click(object sender, RoutedEventArgs e)
    {
    
        StringBuilder result = new StringBuilder("Pfx file selection ");
        FileOpenPicker pfxFilePicker = new FileOpenPicker();
        pfxFilePicker.FileTypeFilter.Add(".pfx");
        pfxFilePicker.CommitButtonText = "Open";
        try
        {
            StorageFile pfxFile = await pfxFilePicker.PickSingleFileAsync();
            if (pfxFile != null)
            {
                IBuffer buffer = await FileIO.ReadBufferAsync(pfxFile);
                using (DataReader dataReader = DataReader.FromBuffer(buffer))
                {
                    byte[] bytes = new byte[buffer.Length];
                    dataReader.ReadBytes(bytes);
                    pfxCert = System.Convert.ToBase64String(bytes);
                    PfxPassword.Password = string.Empty;
                    result.Append("succeeded");
                }
            }
            else
            {
                result.Append("failed");
            }
        }
        catch (Exception ex)
        {
            result.Append("failed with ");
            result.Append(ex.Message); ;
        }
    
        Result.Text = result.ToString();
    }
    
  8. 运行应用并登录到安全 Web 服务以及将 PFX 文件导入到本地证书存储中。Run your app and log in to your secured web service as well as import a PFX file into the local certificate store.

可使用这些步骤创建多个应用,这些应用使用同一个用户证书访问相同或不同的安全 Web 服务。You can use these steps to create multiple apps that use the same user certificate to access the same or different secured web services.