为 IIS 7.0 和 7.5 配置多对一客户端证书映射

本文介绍如何使用 Microsoft Internet Information Services (IIS) 中的配置编辑器功能来配置多对一客户端证书映射。

原始产品版本: Internet Information Services 7.0、7.5
原始 KB 编号: 2026113

简介

当客户端证书用于用户身份验证时,IIS 使用多对一客户端证书映射将最终用户关联到 Windows 帐户。 用户的会话由 IIS 在此映射的 Windows 帐户的上下文下执行。 若要按预期工作,需要确保在 IIS 中正确配置证书到帐户映射。

在 IIS 6.0 中,用户可以选择通过 IIS 管理器用户界面配置多对一客户端证书映射。 在 IIS 7.0 和 7.5 中,该接口不存在于一对一或多对一映射中。 本文介绍如何使用 IIS 的配置编辑器功能来配置多对一客户端证书映射。

注意

有关使用配置编辑器配置一对一客户端证书映射的信息,请参阅配置一对一客户端证书映射

IIS 7.0/7.5 架构

这是 IIS 7.0 和 IIS 7.5 中 IIS 客户端证书映射身份验证功能的架构:

<sectionSchema name="system.webServer/security/authentication/iisClientCertificateMappingAuthentication">
   <attribute name="enabled" type="bool" defaultValue="false" />
   <attribute name="manyToOneCertificateMappingsEnabled" type="bool" defaultValue="true" />
   ...
   <element name="manyToOneMappings">
     <collection addElement="add" clearElement="clear">
       <attribute name="name" type="string" required="true" isUniqueKey="true"
       validationType="nonEmptyString" />
       <attribute name="description" type="string" />
       <attribute name="enabled" type="bool" defaultValue="true"/>
       <attribute name="permissionMode" type="enum" defaultValue="Allow">
         <enum name="Allow" value="1"/>
         <enum name="Deny" value="2" />
       </attribute>
       <element name="rules">
         <collection addElement="add" clearElement="clear">
           <attribute name="certificateField" type="enum" required="true" isCombinedKey="true">
             <enum name="Subject" value="1" />
             <enum name="Issuer" value="2" />
           </attribute>
           <attribute name="certificateSubField" type="string" caseSensitive="true"
           required="true" isCombinedKey="true" />
           <attribute name="matchCriteria" type="string" caseSensitive="true"
           required="true" isCombinedKey="true" />
           <attribute name="compareCaseSensitive" type="bool" isCombinedKey="true" defaultValue="true" />
         </collection>
       </element>
       <attribute name="userName" type="string" validationType="nonEmptyString" />
       <attribute name="password" type="string" caseSensitive="true" encrypted="true"
       defaultValue="[enc:AesProvider::enc]" />
     </collection>
   </element>
   ...
</sectionSchema>

先决条件

下面是此演练所需的先决条件:

  1. 已在 IIS 服务器上安装了 IIS 客户端证书映射模块。

  2. 网站配置了超文本传输协议安全 (HTTPS) 绑定,该绑定可以接受安全套接字层 (SSL) 连接。

  3. 客户端上安装有客户端证书。

  4. IIS 7 管理包安装在 IIS 7.0 服务器上。

    注意

    默认情况下,配置编辑器在 IIS 7.5 上提供。

通过配置编辑器配置证书映射

  1. 启动 IIS 管理器,然后选择要配置用于客户端证书身份验证的网站。

  2. “功能视图”中,选择“管理”部分下的“配置编辑器”。

    在“功能视图”中选择“管理”下的“配置”编辑器。

  3. 在下拉框中转到 system.webServer/security/authentication/iisClientCertificateMappingAuthentication ,如下所示:

    在身份验证下选择 iisClientCertificateMappingAuthentication。

    你将在此处看到一个用于配置多对一或一对一证书映射的窗口。 这是通过配置编辑器提供的 UI,可在其中设置所有映射配置。

    用于设置所有映射配置的窗口的屏幕截图。

  4. 通过此图形用户界面 (GUI) 修改属性。

    • “启用” 设置为 “True”。
    • manyToOneCertificateMappingsEnabled 设置为 True
    • 选择 “manyToOneMappings ”,然后在省略号按钮上选择,以启动用于配置映射的新窗口。
  5. 在此新窗口下,选择以添加新项。 可以从窗口中修改属性,如下所示:

    用于修改新项的属性的窗口的屏幕截图。

  6. 规则的省略号按钮上选择,这将提供根据证书属性添加多个匹配模式的选项。

    用于添加多个模式的屏幕截图 1。

    用于添加多个模式的屏幕截图 2。

    用于添加多个模式的屏幕截图 3。

在这些示例图像中,有两个用于映射证书的规则条目。

首先,证书中有 “使用者” 和“ 颁发者 ”字段。 其次,还有 matchcriteria 属性,用于将证书映射到帐户 mydomain\testuser

下图演示了特定 Windows 帐户的最终映射。 可以看到,此帐户 的规则 有两个条目。

包含两个规则条目的项的屏幕截图。

同样,可以根据证书中的 “颁发者”“使用者 ”字段为帐户创建其他映射。

按 APPCMD.exe 配置证书映射

到目前为止,已演示的内容是使用配置编辑器实现的,它提供了一个图形界面来轻松设置配置。 可以使用命令实现相同的操作APPCMD.exe,事实上,配置编辑器在后台执行相同的操作,并将这些设置添加到 ApplicationHost.config 文件中。

配置编辑器还提供了手动运行这些命令的选项,并生成脚本以从 UI 本身内部实现:

选择“生成脚本”选项以运行命令。

在“脚本对话框”窗口中手动运行命令。

这些是执行上述相同步骤以配置证书映射的代码片段。 它们是使用配置编辑器的脚本生成功能生成的。

AppCmd 命令

appcmd.exe set config "Default Web Site" -section:system.webServer/security/authentication/iisClientCertificateMappingAuthentication /enabled:"True" /manyToOneCertificateMappingsEnabled:"True"  /commit:apphost
appcmd.exe set config "Default Web Site" -section:system.webServer/security/authentication/iisClientCertificateMappingAuthentication /+"manyToOneMappings.[name='My 1st  Mapping',description='1st User Mapping',userName='mydomain\testuser',password='abcdef']" /commit:apphost
appcmd.exe set config "Default Web Site" -section:system.webServer/security/authentication/iisClientCertificateMappingAuthentication /+"manyToOneMappings.[name='My 1st  Mapping',description='1st User Mapping',userName='mydomain\testuser',password='abcdef'].rules.[certificateField='Subject',certificateSubField='CN',matchCriteria='Test User']" /commit:apphost

C# 代码

using System.Text;
using Microsoft.Web.Administration;
internal static class Sample {
    private static void Main() {
        using(ServerManager serverManager = new ServerManager())
        {
            Configuration config = serverManager.GetApplicationHostConfiguration();
            ConfigurationSection iisClientCertificateMappingAuthenticationSection =
            config.GetSection("system.webServer/security/authentication/iisClientCertificateMappingAuthentication", "Default Web Site");
            iisClientCertificateMappingAuthenticationSection["enabled"] = true;
            iisClientCertificateMappingAuthenticationSection["manyToOneCertificateMappingsEnabled"] = true;
            ConfigurationElementCollection manyToOneMappingsCollection = iisClientCertificateMappingAuthenticationSection.GetCollection("manyToOneMappings");
            ConfigurationElement addElement = manyToOneMappingsCollection.CreateElement("add");
            addElement["name"] = @"My 1st  Mapping";
            addElement["description"] = @"1st User Mapping";
            addElement["userName"] = @"mydomain\testuser";
            addElement["password"] = @"abcdef";
            ConfigurationElementCollection rulesCollection = addElement.GetCollection("rules");
            ConfigurationElement addElement1 = rulesCollection.CreateElement("add");
            addElement1["certificateField"] = @"Subject";
            addElement1["certificateSubField"] = @"CN";
            addElement1["matchCriteria"] = @"Test User";
            rulesCollection.Add(addElement1);
            manyToOneMappingsCollection.Add(addElement);
            serverManager.CommitChanges();
        }
    }
}

编写 javaScript) (脚本

var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
var iisClientCertificateMappingAuthenticationSection = adminManager.GetAdminSection("system.webServer/security/authentication/iisClientCertificateMappingAuthentication", "MACHINE/WEBROOT/APPHOST/Default Web Site");
iisClientCertificateMappingAuthenticationSection.Properties.Item("enabled").Value = true;
iisClientCertificateMappingAuthenticationSection.Properties.Item("manyToOneCertificateMappingsEnabled").Value = true;
var manyToOneMappingsCollection = iisClientCertificateMappingAuthenticationSection.ChildElements.Item("manyToOneMappings").Collection;
var addElement = manyToOneMappingsCollection.CreateNewElement("add");
addElement.Properties.Item("name").Value = "My 1st  Mapping";
addElement.Properties.Item("description").Value = "1st User Mapping";
addElement.Properties.Item("userName").Value = "mydomain\\testuser";
addElement.Properties.Item("password").Value = "abcdef";
var rulesCollection = addElement.ChildElements.Item("rules").Collection;
var addElement1 = rulesCollection.CreateNewElement("add");
addElement1.Properties.Item("certificateField").Value = "Subject";
addElement1.Properties.Item("certificateSubField").Value = "CN";
addElement1.Properties.Item("matchCriteria").Value = "Test User";
rulesCollection.AddElement(addElement1);
manyToOneMappingsCollection.AddElement(addElement);
adminManager.CommitChanges();