概述

集成 Windows 身份验证在 Intranet 环境中使用最频繁,因为它要求执行身份验证的服务器和正在进行身份验证的用户属于同一域。 要使用户自动进行身份验证,用户使用的客户端计算机也必须是域的一部分。

使用 Apache Tomcat 实现集成的 Windows 身份验证有多种选择。他们是:

  • 内置 Tomcat 支持。

  • 使用第三方库,如 Waffle。

  • 使用支持 Windows 身份验证的反向代理执行身份验证步骤,例如 IIS 或 httpd。

以下各节将讨论每个选项的配置。

内置 Tomcat 支持

Kerberos(集成 Windows 身份验证的基础)需要仔细配置。 如果完全遵循本指南中的步骤,则将生成工作配置。请务必严格遵循以下步骤。 配置的灵活性空间非常小。从测试到如今,已知:

  • 用于访问 Tomcat 服务器的主机名必须与 SPN 中的主机名完全匹配,否则身份验证将失败。在这种情况下,调试日志中可能会报告校验和错误。

  • 客户端必须认为服务器是本地可信 Intranet 的一部分。

  • SPN 必须是 HTTP/<hostname>,并且在使用它的所有位置都必须完全相同。

  • SPN 中不得包含端口号。

  • 一个域用户不能映射多个 SPN。

  • Tomcat 必须以与 SPN 关联的域帐户或域管理员身份运行。不建议在域管理员用户下运行 Tomcat。

  • 约定是域名 (dev.local) 始终以小写形式使用。域名通常不区分大小写。

  • 约定是 Kerberos 领域名称 (DEV.LOCAL) 始终以大写形式使用。领域名称区分大小写。

  • 使用 ktpass 命令时,必须指定域。

对 Windows 身份验证的内置 Tomcat 支持的配置有四个组件。 域控制器、托管 Tomcat 的服务器、希望使用 Windows 身份验证的 Web 应用程序和客户端计算机。 以下部分介绍每个组件所需的配置。

下面配置示例中使用的三台计算机的名称是 win-dc01.dev.local(域控制器)、 win-tc01.dev.local(Tomcat 实例)和 win-pc01.dev.local(客户端)。 它们都是 dev.local 域的成员。

注意:为了在以下步骤中使用密码,必须放宽域密码策略。不建议将此选项用于生产环境。

域控制器

这些步骤假定服务器已配置为充当域控制器。将 Windows 服务器配置为域控制器不在本指南的讨论范围之内。 配置域控制器以使 Tomcat 支持 Windows 身份验证的步骤如下:

  • 创建一个域用户,该用户将映射到 Tomcat 服务器使用的服务名称。在本操作指南中,此用户称为 tc01,密码为 tc01pass

  • 将服务主体名称 (SPN) 映射到用户帐户。SPN 采用 <service class>/<host>:<port>/<service name> 的形式。本操作指南中使用的 SPN 是 HTTP/win-tc01.dev.local。要将用户映射到 SPN,请运行以下命令:

setspn -A HTTP/win-tc01.dev.local tc01
  • 生成 Tomcat 服务器将用于向域控制器验证自身身份的密钥表文件。 此文件包含服务提供商帐户的 Tomcat 私钥,应相应地进行保护。 要生成文件,请运行以下命令(全部在一行中):

ktpass /out c:\tomcat.keytab /mapuser tc01@DEV.LOCAL
          /princ HTTP/win-tc01.dev.local@DEV.LOCAL
          /pass tc01pass /kvno 0
  • 创建要在客户端上使用的域用户。在本操作指南中,域用户 test 使用密码 testpass 进行测试。

上述步骤已在运行 Windows Server 2019 Standard 的域控制器上使用森林和域的 Windows Server 2016 功能级别进行了测试。

Tomcat 实例 (Windows Server)

这些步骤假定已经安装并配置了 Tomcat 和适当的Java JDK/JRE, 并且 Tomcat 以 tc01@dev.local 用户身份运行。 配置 Tomcat 实例以进行 Windows 身份验证的步骤如下:

  • 将在域控制器上创建的 tomcat.keytab 文件复制到 $CATALINA_BASE/conf/tomcat.keytab

  • 创建 Kerberos 配置文件 $CATALINA_BASE/conf/krb5.ini。本操作指南中使用的文件包含:

[libdefaults]
default_realm = DEV.LOCAL
default_keytab_name = FILE:c:\apache-tomcat-10.1.x\conf\tomcat.keytab
default_tkt_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
default_tgs_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
forwardable=true

[realms]
DEV.LOCAL = {
        kdc = win-dc01.dev.local:88
}

[domain_realm]
dev.local= DEV.LOCAL
.dev.local= DEV.LOCAL

可以通过设置 java.security.krb5.conf 系统属性来更改此文件的位置。

  • 创建 JAAS 登录配置文件 $CATALINA_BASE/conf/jaas.conf。本操作指南中使用的文件包含:

com.sun.security.jgss.krb5.initiate {
    com.sun.security.auth.module.Krb5LoginModule required
    doNotPrompt=true
    principal="HTTP/win-tc01.dev.local@DEV.LOCAL"
    useKeyTab=true
    keyTab="c:/apache-tomcat-10.1.x/conf/tomcat.keytab"
    storeKey=true;
};

com.sun.security.jgss.krb5.accept {
    com.sun.security.auth.module.Krb5LoginModule required
    doNotPrompt=true
    principal="HTTP/win-tc01.dev.local@DEV.LOCAL"
    useKeyTab=true
    keyTab="c:/apache-tomcat-10.1.x/conf/tomcat.keytab"
    storeKey=true;
};

可以通过设置 java.security.auth.login.config 系统属性来更改此文件的位置。 使用的 LoginModule 是特定于 JVM 的 LoginModule,因此请确保指定的 LoginModule 与正在使用的 JVM 匹配。 登录配置的名称必须与身份验证 Valve 使用的值匹配。

SPNEGO 身份验证器将与任何 Realm 一起使用,但如果与 JNDI Realm 一起使用, 则默认情况下,JNDI Realm 将使用用户的委托凭证连接到 Active Directory。 如果只需要经过身份验证的用户名,则可以使用 AuthenticatedUserRealm, 它将简单地基于经过身份验证的用户名返回一个 Principal,该用户名没有任何角色。

上述步骤已在运行 Windows Server 2019 Standard 和 AdoptOpenJDK 8u232-b09(64 位)的 Tomcat 服务器上进行了测试。

Tomcat 实例(Linux 服务器)

使用以下方法进行了测试:

  • Java 1.7.0,更新 45,64 位

  • Ubuntu Server 12.04.3 LTS 64 位

  • Tomcat 8.0.x (r1546570)

它应该适用于任何 Tomcat 版本,但建议使用最新的稳定版本。

配置与 Windows 相同,但有以下更改:

  • Linux 服务器不必是 Windows 域的一部分。

  • 应更新 krb5.ini 和 jaas.conf 中密钥表文件的路径,以使用 Linux 样式文件路径(例如 /usr/local/tomcat/…​)反映 Linux 服务器上密钥表文件的路径。

Web 应用程序

Web 应用程序需要配置为在 web.xml 中使用 `SPNEGO `的特定于 Tomcat 的身份验证方法(而不是 BASIC 等)。 与其他身份验证器一样,可以通过显式配置身份验证 valve 并在 Valve 上设置属性来自定义行为。

客户端

必须将客户端配置为使用 Kerberos 身份验证。 对于 Internet Explorer,这意味着确保 Tomcat 实例位于“本地 Intranet”安全域中, 并且其配置(Tools > Internet Options > Advanced)启用了集成的 Windows 身份验证。 请注意,如果客户端和Tomcat 实例使用同一台计算机,不起作用,因为 Internet Explorer 将使用不受支持的 NTLM 协议。

引用

正确配置 Kerberos 身份验证可能很棘手。 以下参考资料可能会有所帮助。Tomcat 用户邮件列表也始终提供建议。

  1. IIS 和 Kerberos

  2. SourceForge 上的 SPNEGO 项目

  3. Oracle Java GSS-API 教程 (Java 7)

  4. Oracle Java GSS-API 教程 — 疑难解答 (Java 7)

  5. 用于 Windows 身份验证的 Geronimo 配置

  6. Kerberos 交换中的加密选择

  7. 支持的 Kerberos 密码套件

第三方库

Waffle

此解决方案的完整详细信息可通过 Waffle 网站找到。主要特点是:

  • 即用型 solution

  • 配置简单(无需 JAAS 或 Kerberos 密钥表配置)

  • 使用本机库

Spring Security - Kerberos 扩展

可以通过 Kerberos 扩展网站找到此解决方案的完整详细信息。主要特点是:

  • 对 Spring Security 的扩展

  • 需要生成 Kerberos 密钥表文件

  • 纯 Java 解决方案

Jespa

可以通过 Project Web 站点找到此解决方案的完整详细信息。主要特点是:

  • 纯 Java 解决方案

  • 高级 Active Directory 集成

SourceForge 的 SPNEGO AD 项目

此解决方案的完整详细信息可通过项目站点找到。主要特点是:

  • 纯 Java 解决方案

  • SPNEGO/Kerberos 身份验证器

  • Active Directory 领域

反向代理

Microsoft IIS

配置 IIS 以提供 Windows 身份验证有三个步骤。他们是:

  1. 将 IIS 配置为 Tomcat 的反向代理(请参阅 IIS Web 服务器操作指南)。

  2. 将 IIS 配置为使用 Windows 身份验证

  3. 通过将 AJP 连接器上的 tomcatAuthentication 属性设置为 false,将 Tomcat 配置为使用 IIS 中的身份验证用户信息。 或者,将 tomcatAuthorization 属性设置为 true,以允许 IIS 进行身份验证,同时 Tomcat 执行授权。

Apache httpd

Apache httpd 不支持开箱即用的 Windows 身份验证,但可以使用许多第三方模块。这些包括:

  • mod_auth_sspi 在 Windows 平台上使用。

  • mod_auth_ntlm_winbind 适用于非 Windows 平台。已知可在 32 位平台上使用 httpd 2.0.x。 一些用户报告了 httpd 2.2.x 版本和 64 位 Linux 版本的稳定性问题。

配置 httpd 以提供 Windows 身份验证有三个步骤:

  1. 将 httpd 配置为 Tomcat 的反向代理(请参见 Apache httpd Web 服务器操作指南)。

  2. 配置 httpd 以使用 Windows 身份验证

  3. 通过将 AJP 连接器上的 tomcatAuthentication 属性设置为 false, 将 Tomcat 配置为使用 httpd 中的身份验证用户信息。