Windows 认证操作指南

目录

概述

集成 Windows 认证最常用于内部网络环境,因为它要求执行认证的服务器和被认证的用户属于同一域。为了用户能够自动认证,用户使用的客户端机器也必须是该域的一部分。

使用 Apache Tomcat 实现集成 Windows 认证有以下几种选项:

  • Tomcat 内置支持。
  • 使用第三方库,如 Waffle。
  • 使用支持 Windows 认证的反向代理(如 IIS 或 httpd)来执行认证步骤。

这些选项的配置将在以下章节中讨论。

Tomcat 内置支持

Kerberos(集成 Windows 认证的基础)需要仔细配置。如果严格遵循本指南中的步骤,则将得到一个可用的配置。重要的是要严格遵循以下步骤。配置的灵活性非常小。根据目前的测试可知:

  • 用于访问 Tomcat 服务器的主机名必须与 SPN 中的主机名完全匹配,否则认证将失败。在这种情况下,调试日志中可能会报告校验和错误。
  • 客户端必须认为服务器是本地受信任内部网络的一部分。
  • SPN 必须是 HTTP/<hostname>,并且在所有使用它的地方都必须完全相同。
  • SPN 中不得包含端口号。
  • 一个域用户只能映射一个 SPN。
  • Tomcat 必须以与 SPN 相关联的域账户运行,或者以域管理员身份运行。建议在域管理员用户下运行 Tomcat。
  • 惯例是域名 (dev.local) 始终使用小写。域名通常不区分大小写。
  • 惯例是 Kerberos 领域名称 (DEV.LOCAL) 始终使用大写。领域名称区分大小写。
  • 使用 ktpass 命令时必须指定域。

内置 Tomcat 支持 Windows 认证的配置有四个组成部分:域控制器、托管 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 服务器用于向域控制器进行认证的 keytab 文件。此文件包含服务提供者帐户的 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 服务器)

这些步骤假定 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-11.0.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-11.0.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-11.0.x/conf/tomcat.keytab"
        storeKey=true;
    };
    可以通过设置 java.security.auth.login.config 系统属性来更改此文件的位置。所使用的 LoginModule 是特定于 JVM 的,因此请确保指定的 LoginModule 与正在使用的 JVM 匹配。登录配置的名称必须与 认证阀门 使用的值匹配。

SPNEGO 认证器可以与任何 域 (Realm) 配合使用,但如果与 JNDI 域 (JNDI Realm) 配合使用,JNDI 域默认将使用用户的委派凭据连接到 Active Directory。如果只需要认证的用户名称,则可以使用 AuthenticatedUserRealm,它将简单地返回一个基于认证用户名称的 Principal,该 Principal 不包含任何角色。

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

Tomcat 实例 (Linux 服务器)

这已使用以下配置进行测试:

  • Java 1.7.0, update 45, 64位
  • Ubuntu Server 12.04.3 LTS 64位
  • Tomcat 8.0.x (r1546570)

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

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

  • Linux 服务器不必是 Windows 域的一部分。
  • krb5.ini 和 jaas.conf 中 keytab 文件的路径应更新为反映 Linux 服务器上 keytab 文件的路径,使用 Linux 风格的文件路径(例如 /usr/local/tomcat/...)。

Web 应用程序

Web 应用程序需要在 web.xml 中配置为使用 Tomcat 特定的 SPNEGO 认证方法(而不是 BASIC 等)。与其他认证器一样,可以通过显式配置 认证阀门 并设置其属性来定制行为。

客户端

客户端必须配置为使用 Kerberos 认证。对于 Internet Explorer,这意味着确保 Tomcat 实例位于“本地 Intranet”安全域中,并且已配置(工具 > Internet 选项 > 高级)并启用集成 Windows 认证。请注意,如果您在同一台机器上同时用作客户端和 Tomcat 实例,这将不起作用,因为 Internet Explorer 将使用不受支持的 NTLM 协议。

第三方库

Waffle

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

  • 即插即用解决方案
  • 简单配置(无需 JAAS 或 Kerberos keytab 配置)
  • 使用原生库

Spring Security - Kerberos 扩展

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

  • Spring Security 扩展
  • 需要生成 Kerberos keytab 文件
  • 纯 Java 解决方案

Jespa

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

  • 纯 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 认证,但有许多第三方模块可用于此目的。其中包括:

  1. 用于 Windows 平台的 mod_auth_sspi
  2. 用于非 Windows 平台的 mod_auth_ntlm_winbind。已知在 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 的认证用户信息。