如何在Python中获取Kerberos令牌?我有可用的 C# 和 PS 语法,但想转换它

问题描述 投票:0回答:1

我正在尝试使用 Python 来获取 Kerberos 安全令牌。我有一些确实需要的 C# 清晰语法,但我不知道从哪里开始将其转换为 Python。这是 C# 代码:

{
            AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
            var domain = Domain.GetCurrentDomain().ToString();
            using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
            {
                KerberosSecurityTokenProvider tokenProvider = new KerberosSecurityTokenProvider(serviceName, System.Security.Principal.TokenImpersonationLevel.Identification, CredentialCache.DefaultNetworkCredentials);
                KerberosRequestorSecurityToken securityToken = tokenProvider.GetToken(TimeSpan.FromMinutes(5)) as KerberosRequestorSecurityToken;
                string serviceToken = Convert.ToBase64String(securityToken.GetRequest());
}

我尝试使用“microsoft.identitymodel.dll”并使用 ctype 和 clr 库,但是,我对 Python 还很陌生,所以我不确定这是否是正确的途径。我还有一些 Powershell 代码可以满足我的需要:

[System.IdentityModel.Selectors.KerberosSecurityTokenProvider]$tokenProvider = [System.IdentityModel.Selectors.KerberosSecurityTokenProvider]::new($ServicePrincipalName, [System.Security.Principal.TokenImpersonationLevel]::Identification, $PSBoundParameters.Credential)

我知道 $ServicePrincipalName 应该是什么,我知道我可以使用子进程库,只需使用 Powershell.exe 调用命令,但我想将所有内容保留在 Python 中。

如有任何帮助,我们将不胜感激!

python c# dll kerberos
1个回答
1
投票

Windows 身份验证的主要非 CLR 接口是 SSPI(类似于 Linux 上的 GSSAPI)。 CLR 库只是 SSPI 的精美包装,因此不要浪费时间尝试从 Python 使用它们 - 这比直接使用 SSPI 需要更多工作。

如果您只在 Windows 上工作,请尝试作为 pywin32

 一部分的 
sspi 模块,或新的
sspilib
模块。谷歌告诉我“sspi”模块的工作原理有点像这样

import sspi
context = sspi.ClientAuth(pkg_name="Negotiate",
                          targetspn="HTTP/foo.example.com")
# [receive input_token from server]
while True:
    err, bufs = context.authorize(input_token)
    output_token = bufs[0].Buffer
    # [send output_token to server, receive input_token back]
    if err == 0:
        break

SSPI/GSSAPI 的基本模型是“循环调用 step() 直到机制报告完成”,但对于 HTTP Negotiate 身份验证只有一步(并且输入令牌通常为空),因此您可以跳过循环:

import sspi
ctx = sspi.ClientAuth("Negotiate",
                      targetspn="HTTP/foo.example.com")
in_token = None
err, bufs = ctx.authorize(in_token)
assert(err == 0)
out_token = bufs[0].Buffer

或使用sspilib:

import sspilib
creds = sspilib.UserCredential(usage="initiate",
                               protocol="Negotiate",
                               protocol_list=["!ntlm"])
ctx = sspilib.ClientSecurityContext(target_name="HTTP/foo.example.com",
                                    credential=creds)
out_token = ctx.step(in_token)

由于大多数 Windows 协议使用 SPNEGO 而不是原始 Kerberos,因此 python-pyspnego 将是跨平台操作的最佳选择 - 它通过 Windows SSPI 和 Unix GSSAPI 提供到 SPNEGO 的统一接口。 (它也可以在 Unix 上执行 NTLM。)

import spnego
ctx = spnego.client(hostname="foo.example.com",
                    service="HTTP",
                    protocol="negotiate")
in_token = None
out_token = ctx.step(in_token)

sspi
模块的Linux/Unix等价物是python-gssapi,它使用非常相似的概念。但是,默认情况下它处理原始 Kerberos 令牌,而不是 SPNEGO 令牌。 import gssapi target = gssapi.Name("[email protected]", gssapi.NameType.hostbased_service) ctx = gssapi.SecurityContext(name=target, usage="initiate") in_token = None out_token = ctx.step(in_token)

要强制其使用 SPNEGO,请使用:

SPNEGO = gssapi.Mechanism.from_sasl_name("SPNEGO") ctx = gssapi.SecurityContext(name=target, mech=SPNEGO, usage="initiate")

(注意:
不要

在 Windows 上安装 gssapi 模块 – 如果这样做,那么

spnego
模块将停止使用 SSPI,并开始抱怨缺少 MIT GSSAPI 库。)
还有另外两个模块:用于 GSSAPI (Unix) 的 

pykerberos

和用于 SSPI (Windows) 的 winkerberos。它们的工作原理类似,但它们提供的 API 有点丑陋且非 Python 风格(pykerberos 最初是 MacOS 中 Objective-C 接口的包装器)。 当然,如果您尝试将其用于 HTTP,那么已经有几个模块可以实现 – 例如

requests-kerberos

通过 pyspnego 添加 SSPI(和 GSSAPI)支持: import requests import requests_kerberos resp = requests.get("https://foo.example.com", auth=requests_kerberos.HTTPKerberosAuth())

类似地,
requests-gssapi

httpx-gssapi 在 Unix 上通过 gssapi 执行相同的操作。


    

© www.soinside.com 2019 - 2024. All rights reserved.