【发布时间】:2018-08-15 15:08:48
【问题描述】:
我正在尝试从使用 Kerberos 身份验证的 Intranet 站点请求 json 响应。
我像这样制作了一个 kinit(没有 keytab):
kinit employee_id@CORP.MYCOMPANY.COM
执行此操作后,以下代码可以正常工作,并为我提供我想要的确切 json 响应:
def __make_request(self):
curl = pycurl.Curl()
data = BytesIO()
curl.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_GSSNEGOTIATE)
curl.setopt(pycurl.USERPWD, self.pwd)
curl.setopt(pycurl.WRITEFUNCTION, data.write)
curl.setopt(pycurl.URL, self.url)
curl.perform()
curl.close()
return json.loads(data.getvalue())
这当然看起来太容易了。我决定用 gssapi 试试:
server_name = gssapi.Name('HTTP/service_principal_here@OTHER_REALM.COM') <-listed on TGT
canon_name = server_name.canonicalize(gssapi.MechType.kerberos)
ctx = gssapi.SecurityContext(name=canon_name, usage='initiate')
token = ctx.step()
token64 = base64.b64encode(token)
(token64 将打印一个长编码令牌)
h = {"www-authenticate": "Negotiate " + token64}
r = requests.get("same url used with pycurl above", headers = h)
这会导致 403(不是 401)
对我的请求有什么问题有任何想法吗?
【问题讨论】:
-
出于好奇,该 Intranet 站点如何处理 会话凭据?通常认为对所有请求强制执行 SPNego/Kerberos 是一种不好的做法,因为它效率低下;例如,Hadoop 生态系统使用存储在“签名 cookie” 中的会话令牌(有一个例外,客户端必须显式检索令牌,然后在 URL 中显式传递它)。您似乎没有管理 cookie,所以我想知道。
-
会话凭据是什么意思?在我的真实代码中,我得到 klist -s 的 o/p(通过子进程模块)并检查返回码是否为 0(表示有效票证)。显然我的员工 ID 和 REALM(在执行 kinit 时使用)就足够了,因为它被列为服务主体?你是说我不应该只为每个请求创建一个令牌..而是检查是否已经有一个令牌?到目前为止,我只检查 TGT 是否有效(默认为 10 小时),然后创建一个令牌。
-
我想我还应该提到这个令牌的唯一用户是我的 Flask Web 应用程序,即:Intranet 站点(当它需要访问其他服务器以获得 json 响应时)
-
Kerberos 使用 票证。应用程序可以在内部使用 tokens。强身份验证一次,针对特定服务器上的特定服务,然后只是对所有服务器/容器有效的令牌,但仅几分钟。
-
知道了。感谢您的帮助
标签: python authentication python-requests kerberos gssapi