杰瑞科技汇

Python Kerberos认证如何配置与使用?

在 Python 中,处理 Kerberos 认证最常用、最可靠的库是 requests-kerberos,它封装了底层的 Kerberos 协议,并提供了与 requests 库无缝集成的方式。

Python Kerberos认证如何配置与使用?-图1
(图片来源网络,侵删)

下面我将分步讲解整个流程,包括环境准备、代码实现和常见问题。


核心概念:Kerberos 是如何工作的?

在写代码之前,理解 Kerberos 的基本流程非常重要,它主要涉及三个角色:

  1. 客户端: 请求服务的用户或应用程序(比如你的 Python 脚本)。
  2. Key Distribution Center (KDC): 信任的中心服务器,负责发放票据,在 AD 环境中,这通常就是你的域控制器。
  3. 服务端: 客户端想要访问的服务(一个支持 Kerberos 认证的 Web 服务器)。

基本流程:

  1. 认证: 客户端首先向 KDC 证明自己的身份,获取一个 票据授予票据,这个过程通常需要用户的密码(通过 kinit 命令完成)。
  2. 请求服务票据: 客户端拿着 TGT 向 KDC 请求访问特定服务的 服务票据
  3. 访问服务: 客户端将服务票据发送给服务端,服务端验证票据的有效性,如果成功,就授予客户端访问权限。

对于 Python requests-kerberos 库可以帮助我们自动完成步骤 2 和 3,但步骤 1(获取 TGT)是前提,它通常在登录时通过操作系统完成。

Python Kerberos认证如何配置与使用?-图2
(图片来源网络,侵删)

环境准备

在开始之前,你的系统必须已经配置好 Kerberos 客户端。

1 Linux/macOS

你需要安装 Kerberos 客户端工具。

对于 Debian/Ubuntu:

sudo apt-get install krb5-user

对于 CentOS/RHEL/Fedora:

sudo yum install krb5-workstation

安装后,你需要配置 Kerberos,主要配置文件是 /etc/krb5.conf,这个文件通常由系统管理员提供,你需要确保它正确指向了你的 KDC(域控制器)。

配置示例 (/etc/krb5.conf):

[libdefaults]
    default_realm = YOUR_COMPANY.COM  # 你的 Active Directory 域名,必须是大写
[realms]
    YOUR_COMPANY.COM = {
        kdc = dc1.your_company.com
        kdc = dc2.your_company.com
        admin_server = dc1.your_company.com
    }
[domain_realm]
    .your_company.com = YOUR_COMPANY.COM

2 Windows

在 Windows 上,Kerberos 客户端是内置的,你只需要确保你的计算机已经加入到 Active Directory 域中。

获取 TGT (票据授予票据): 打开命令提示符或 PowerShell,运行 kinit 命令并输入你的域密码。

# 格式: kinit <username>@<DOMAIN>
kinit john.doe@YOUR_COMPANY.COM

如果成功,你不会有任何输出,但你的当前会话已经获得了 Kerberos 票据,你可以用 klist 命令查看当前持有的票据。


Python 代码实现 (requests-kerberos)

1 安装库

安装 requests-kerberos

pip install requests requests-kerberos

2 认证模式

requests-kerberos 主要支持两种认证模式:

  1. HTTPKerberosAuth (自动协商): 这是最常用的模式,它会自动尝试使用当前登录会话中的 Kerberos 凭据(TGT),如果你已经用 kinit 获取了票据,它会直接使用。
  2. Negotiate (仅协商): 这种模式只发送 Negotiate 头,但不会主动发送用户名或密码,它依赖于服务器和客户端之间的后续协商来获取凭据,在某些代理或特定配置的服务器上可能需要。

我们主要介绍第一种模式。

3 示例代码

假设你需要访问一个受 Kerberos 保护的 Web API,该 API 的地址是 https://internal-api.your_company.com/secure-data

import requests
from requests_kerberos import HTTPKerberosAuth, OPTIONAL
# 1. 定义目标服务的 URL
# 这个 URL 的主机名必须是 Kerberos 服务主体名称 的一部分
# 如果 SPN 是 'HTTP/internal-api.your_company.com@YOUR_COMPANY.COM'
# 那么这里的 URL 就应该是 'https://internal-api.your_company.com/...'
url = 'https://internal-api.your_company.com/secure-data'
# 2. 创建一个 HTTPKerberosAuth 对象
# 这个对象会自动使用当前会话中的 Kerberos 票据
# mutual_authentication=OPTIONAL 表示如果服务器要求双向认证,则参与,否则不参与
# 也可以设置为 REQUIRED (必须) 或 NONE (不参与)
kerberos_auth = HTTPKerberosAuth(mutual_authentication=OPTIONAL)
print(f"正在尝试使用 Kerberos 认证访问: {url}")
try:
    # 3. 发送 GET 请求,将 auth 对象传递给 requests
    response = requests.get(url, auth=kerberos_auth, verify=True) # verify=True 表示验证 SSL 证书
    # 4. 检查响应状态码
    if response.status_code == 200:
        print("认证成功!")
        print("响应内容:")
        print(response.json())
    else:
        print(f"请求失败,状态码: {response.status_code}")
        print("响应内容:")
        print(response.text)
except requests.exceptions.RequestException as e:
    print(f"请求发生错误: {e}")
except Exception as e:
    print(f"发生未知错误: {e}")

4 如何确定服务主体名称?

Kerberos 的核心是 服务主体名称,客户端必须知道要向哪个 SPN 请求服务票据。

  • SPN 格式: <SERVICE_CLASS>/<HOSTNAME>@<REALM>

    • SERVICE_CLASS: 通常是 HTTP (对于 Web 服务)。
    • HOSTNAME: 服务的完整主机名 (api-server.your_company.com)。
    • REALM: 服务所在的 Kerberos 域 (YOUR_COMPANY.COM)。
  • 如何查找 SPN?

    • 在 Windows AD 中: 你可以使用 AD 用户和计算机管理工具,或者在域控制器上运行 setspn 命令来查看和管理 SPN。
      # 查看某个账户注册的所有 SPN
      setspn -l <service_account_name>
    • 服务端配置: Web 服务器(如 IIS, Apache)通常需要配置其使用的 SPN,这通常是在 AD 中为运行服务的服务账户注册 SPN。

如果你的 URL 是 https://appserver.domain.com,那么客户端很可能需要向 HTTP/appserver.domain.com@DOMAIN.COM 这个 SPN 请求票据。requests-kerberos 通常能从 URL 中自动推断出 SPN。


常见问题与解决方案

1 gssapi 模块未找到 (ModuleNotFoundError: No module named 'gssapi')**

问题: 运行代码时出现此错误。 原因: requests-kerberos 底层依赖 gssapi 库来与系统的 Kerberos 库通信,这个库的 Python 绑定没有安装。 解决方案:

  • Linux (Debian/Ubuntu):
    sudo apt-get install python3-gssapi
  • Linux (CentOS/RHEL):
    sudo yum install python3-gssapi
  • Windows: 通常不需要单独安装,因为它依赖于 Windows 自带的 SSPI (Security Support Provider Interface)。

2 KrbError: Cannot find KDC for realm "YOUR_COMPANY.COM"

问题: 这表示你的系统找不到 KDC。 解决方案:

  1. 检查 /etc/krb5.conf (Linux) 或 Windows 的 Kerberos 配置是否正确。
  2. 确保你的 KDC (域控制器) 的主机名或 IP 地址可以解析。
  3. 确保你的网络可以访问 KDC 的 UDP/TCP 88 (KDC) 和 464 (kadmin) 端口。

3 requests.exceptions.HTTPError: 401 Client Error: Unauthorized

问题: 服务器返回 401 未授权错误。 解决方案:

  1. 检查 TGT: 在 Linux 上运行 klist,在 Windows 上运行 klist,确认你拥有有效的 TGT,并且它没有过期。
    klist
  2. 检查 SPN: 确认客户端请求的 SPN 与服务器在 AD 中注册的 SPN 完全匹配,一个字母或域名的错误大小写都可能导致失败。
  3. 检查服务端配置: 确保服务器确实配置为接受 Kerberos Negotiate 认证。
  4. 检查防火墙: 确保客户端到服务端的流量没有被防火墙阻止。

4 requests.exceptions.SSLError: ...

问题: SSL 证书验证失败。 解决方案:

  1. 最佳实践: 修复服务器端的 SSL 证书,使其受信任。
  2. 临时解决方案 (仅用于测试!): 在 requests.get() 中添加 verify=False 来禁用 SSL 证书验证。
    response = requests.get(url, auth=kerberos_auth, verify=False)

    警告: 这会使你的连接容易受到中间人攻击,绝对不要在生产环境中使用

  1. 环境先行: 确保你的操作系统已正确配置 Kerberos 客户端,并且能用 kinit 成功获取票据。
  2. 安装库: pip install requests requests-kerberos
  3. 编写代码: 使用 requests.get(url, auth=HTTPKerberosAuth()) 即可,库会自动处理复杂的 Kerberos 协议交互。
  4. 排查问题: 遇到问题时,首先检查 klistkrb5.conf 和 AD 中的 SPN 设置,这三个是 Kerberos 认证最常见的故障点。

通过以上步骤,你就可以在 Python 应用中成功集成 Kerberos 认证了。

分享:
扫描分享到社交APP
上一篇
下一篇