快速入门:在 Windows 应用商店应用之间共享用户证书 (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

当对用户进行身份验证时,认证身份验证提供高级别的信任。要求用户名和密码组合以上的安全身份认证的应用可以使用证书进行身份验证。在某些情况下,一组服务将要针对多个 Windows 应用商店应用对用户进行身份验证。本快速入门介绍如何使用同一个证书对多个 Windows 应用商店进行身份验证,以及如何提供方便代码,用户可使用此代码导入提供的证书以访问安全的 Web 服务。

Windows 应用商店应用可使用证书身份验证 Web 服务,多个 Windows 应用商店应用可使用来自证书存储的单个证书对相同的用户进行身份验证。如果证书在存储中不存在,你可以将代码添加到你的应用以从 PFX 文件导入证书。

目标: 采用可从多个 Windows 应用商店应用针对多个安全 Web 服务使用的方法来使用证书,以此对客户进行身份验证。

先决条件

本快速入门仅用于示例目的,并且将使用本地计算机上的 Microsoft Internet Information Services (IIS)。若要运行本快速入门,需要具备:

  • Windows 8.1
  • Microsoft Visual StudioMicrosoft Visual Studio
  • IISMicrosoft Internet Information Server (IIS)

说明

1. 启用 IIS 和客户端证书映射

默认情况下不启用 IIS。可以通过使用 Windows 控制面板来启用 IIS。

  1. 打开“Windows 控制面板”并选择“程序”。
  2. 选择“打开或关闭 Windows 功能”****。
  3. 展开“Internet Information Services”,然后展开“万维网服务”****。展开“应用开发功能”并选择“ASP.NET 3.5”和“ASP.NET 4.5”。 做出这些选择将自动启用 Internet Information Services。
  4. 单击**“确定”**以应用更改。

2. 创建并发布安全的 Web 服务

在此步骤中,你将创建一个安全的 Web 服务并将它发布到你的 IIS 服务器中。

  1. 作为管理员运行 Visual StudioVisual Studio 并从起始页选择“新建项目”。将 Web 服务发布到 IIS 服务器需要管理员访问权限。在“新建项目”对话中,将框架更改为“.NET Framework 3.5”****。选择 Visual C# -> Web -> Visual Studio - > ASP.NET Web 服务应用程序。将应用程序命名为 "FirstContosoBank"。单击“确定”以创建项目。

  2. Service1.asmx.cs 文件中,用以下"登录"方法替换 HelloWorld Web 方法。

            [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 文件。

  4. 解决方案资源管理器中,右键单击 "FirstContosoBank" 应用并选择“发布”。

  5. 在“发布 Web”****对话框中,创建新的配置文件并将其命名为 "ContosoProfile"。单击“下一步”。

  6. 在下一个页面上,为你的 IIS 服务器输入服务器名并指定"默认 Web 站点/FirstContosoBank" 的站点名。单击“发布”****以发布你的 Web 服务。

3. 配置你的 Web 服务以使用客户端认证身份验证。

在此步骤中,你将使用 IIS 管理程序配置你刚刚发布的 Web 服务以要求客户端证书。

  1. 运行“Internet Information Services (IIS) 管理器”。
  2. 展开你的 IIS 服务器的站点。在“默认 Web 站点”下,选择新的 "FirstContosoBank" Web 服务。在“操作”部分中,选择“高级设置...”
  3. 将“应用程序池”设置为“.NET v2.0”****并单击“确定”。
  4. 在“Internet Information Services (IIS) 管理器”****中,选择你的 IIS 服务器,然后双击“服务器证书”。在“操作”部分中,选择“创建自签名证书...”。输入 "ContosoBank" 作为证书的昵称并单击“确定”。这将创建一个新的证书供 IIS 服务器以 "<server-name>.<domain-name>" 格式使用。
  5. 在“Internet Information Services (IIS) 管理器”中,选择默认网站。在“操作”部分中,选择“绑定”,然后单击“添加...”。选择 "https" 作为类型,将端口设置为 "443",,然后输入 IIS 服务器的完整主机名 ("<server-name>.<domain-name>")。将 SSL 证书设置为 "ContosoBank"。单击“确定”。单击“站点绑定”****窗口中的“关闭”。
  6. 在“Internet Information Services (IIS) 管理器”中,选择 "FirstContosoBank" Web 服务。双击“SSL 设置”。选中“要求 SSL”。在“客户端证书”下,选择“要求”。在“操作”部分中,单击“应用”
  7. 你可以通过打开 Web 浏览器并输入以下 Web 地址来验证 Web 服务是否正确配置:"https://<server-name>.<domain-name>/FirstContosoBank/Service1.asmx"。例如,"https://myserver.example.com/FirstContosoBank/Service1.asmx"。如果你的 Web 服务已正确配置,将提示你选择一个客户端证书以访问该 Web 服务。

你可以重复之前的快速入门步骤以创建多个可使用相同的客户端证书访问的 Web 服务。

4. 创建使用证书身份验证的 Windows 应用商店应用

现在你已拥有一个或多个安全 Web 服务,你可以创建使用证书来验证这些 Web 服务的 Windows 应用商店应用。当你使用 HttpClient 对象发出对经过身份验证的 Web 服务的请求时,初始请求将不包含客户端证书。经过身份验证的 Web 服务将以对客户端身份验证的请求进行响应。当此情况发生时,Windows 客户端将自动查询证书存储以获取可用的客户端证书。用户可以从这些证书中选择以对 Web 服务进行身份验证。一些证书受密码保护,所以你将需要向用户提供输入证书密码的方法。

如果没有可用的客户端证书,那么用户将需要将证书添加到证书存储。你可以将代码包括在你的 Windows 应用商店应用中,此应用使用户能够选择一个包含客户端证书的 PFX 文件,然后将该证书导入到客户端证书存储中。

提示  你可以使用 makecert.exe 创建 PFX 文件以用于此快速入门。有关使用 makecert.exe 的信息,请参阅 MakeCert

 

  1. 打开 Visual Studio,然后从起始页中选择“新建项目”。选择 Visual C# -> Windows 应用商店 -> 空白应用 (XAML)。将此新项目命名为 "FirstContosoBankApp"。单击**“确定”**创建新项目。

  2. 在 default.html 文件中,将以下 HTML 添加到默认 body 元素中。此 HTML 包括一个用于浏览要导入的 PFX 文件的按钮、一个用于输入受密码保护的 PFX 文件的密码的文本框、一个用于导入选中的 PFX 文件的按钮、一个用于登录安全 Web 服务的按钮以及一个用于显示当前操作状况的文本块。

    <div>
        <button id="Browse" style="width:400px;height:80px;font-size:18px">Browse for PFX file</button><br />
        PFX password <input id="PfxPassword" type="text" style="width:200px" /> (optional)<br />
        <button id="Import" style="width:400px;height:100px;font-size:20px">Import certificate (PFX file)</button><br />
        <button id="Login" style="width:400px;height:100px;font-size:20px">Login</button>
        <div id="Result" style="width:400px;height:400px;color:white" />
    </div>
    
  3. 保存 default.html 文件。

  4. 在 js 文件夹中,在 default.js 文件中,使用以下变量和函数替换默认的“app.onactivated”函数。它们指定 "FirstContosoBank" 服务的"登录"方法的地址以及承载要导入到证书存储中的 PFX 证书的全局变量。将 <server-name> 更新为你的 IIS 服务器的完全限定的服务器名。

    var pfxPassword;
    var pfxCert;
    var requestUri = new Windows.Foundation.Uri("https://<server-name>/FirstContosoBank/Service1.asmx?op=Login");
    var result;
    
    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
    
            pfxPassword = document.getElementById("PfxPassword");
            result = document.getElementById("Result");
            document.getElementById("Import").addEventListener("click", import_click, false);
            document.getElementById("Login").addEventListener("click", login_click, false);
            document.getElementById("Browse").addEventListener("click", browse_click, false);
    
            args.setPromise(WinJS.UI.processAll());
        }
    };
    
  5. 在 default.js 文件中,添加登录按钮的单击处理程序和访问安全 Web 服务的方法。

    function login_click() {
        makeHttpsCall();
    }
    
    function makeHttpsCall() {
        var returnMessage = "Login ";
    
        var response;
    
        try {
            var httpClient = new Windows.Web.Http.HttpClient();
            httpClient.getAsync(requestUri).then(
                function (response) {
                    if (response) {
                        if (response.statusCode == Windows.Web.Http.HttpStatusCode.ok) {
                            returnMessage += "successful";
                        }
                        else {
                            returnMessage += "failed with ";
                            returnMessage += response.StatusCode;
                        }
    
                        result.innerHTML = returnMessage;
                    }
                });
    
        }
        catch (ex) {
            returnMessage += "failed with ";
            returnMessage += ex.Message;
        }
    
        result.innerHTML = returnMessage;
    }
    
  6. 在 default.js 文件中,添加以下用于浏览 PFX 文件的按钮和用于将选中的 PFX 文件导入到证书存储中的按钮的单击处理程序。

        function import_click() {
            try {
                result.innerHTML += "Importing selected certificate into user certificate store....<br />";
                var certmgr = Windows.Security.Cryptography.Certificates.CertificateEnrollmentManager.userCertificateEnrollmentManager;
                certmgr.importPfxDataAsync(
                    pfxCert,
                    pfxPassword.text,
                    Windows.Security.Cryptography.Certificates.ExportOption.exportable,
                    Windows.Security.Cryptography.Certificates.KeyProtectionLevel.noConsent,
                    Windows.Security.Cryptography.Certificates.InstallOptions.deleteExpired,
                    "Import Pfx").then(
                        function () {
                            result.innerHTML += "Certificate import succeded<br />";
                        });
            }
            catch (ex) {
                result.innerHTML += "Certificate import failed with " + ex.Message + "<br />";
            }
        }
    
        function browse_click() {
            var resultMessage = "Pfx file selection ";
    
            var pfxFilePicker = new Windows.Storage.Pickers.FileOpenPicker();
            pfxFilePicker.fileTypeFilter.append(".pfx");
            pfxFilePicker.commitButtonText = "Open";
    
            try
            {
                pfxFilePicker.pickSingleFileAsync().then(
                    function (pfxFile) {
                        if (pfxFile != null) {
                            Windows.Storage.FileIO.readBufferAsync(pfxFile).then(
                                function (buffer) {
                                    var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(buffer);
                                    var bytes = new Uint8Array(buffer.length);
                                    dataReader.readBytes(bytes);
                                    dataReader.close();
                                    pfxCert = btoa(bytes) 
                                    pfxPassword.text = "";
                                    resultMessage += "succeeded";
                                });
                        }
                        else {
                            resultMessage += "failed";
                        }
                    });
            }
            catch (ex) {
                resultMessage += "failed with ";
                resultMessage += ex.Message;
            }
    
            result.innerHTML = resultMessage;
        }
    
  7. 保存 default.js 文件。

  8. 你现在可以按 F5 来运行 Windows 应用商店应用并登录到你的安全 Web 服务以及将 PFX 文件导入到本地证书存储中。

你可以使用这些步骤创建多个 Windows 应用商店应用,这些应用使用同一个用户证书访问相同或不同的安全 Web 服务。

摘要

在本快速入门中,你学习了如何创建使用客户端证书的安全 Web 服务,以及如何创建可访问该安全 Web 服务的 Windows 应用商店应用。

相关主题

身份验证和用户身份