使用 Python 进行 SSO 的 SPNEGO(kerberos 令牌生成/验证)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/922805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:07:23  来源:igfitidea点击:

SPNEGO (kerberos token generation/validation) for SSO using Python

pythonactive-directorysingle-sign-onkerberosspnego

提问by Parand

I'm attempting to implement a simple Single Sign On scenario where some of the participating servers will be windows (IIS) boxes. It looks like SPNEGO is a reasonable path for this.

我正在尝试实现一个简单的单点登录场景,其中一些参与的服务器将是 Windows (IIS) 框。看起来 SPNEGO 是一个合理的路径。

Here's the scenario:

这是场景:

  • User logs in to my SSO service using his username and password. I authenticate him using some mechanism.
  • At some later time the user wants to access App A.
    • The user's request for App A is intercepted by the SSO service. The SSO service uses SPNEGO to log the user in to App A:
      • The SSO service hits the App A web page, gets a "WWW-Authenticate: Negotiate" response
      • The SSO service generates a "Authorization: Negotiate xxx" response on behalf of the user, responds to App A. The user is now logged in to App A.
    • The SSO service intercepts subsequent user requests for App A, inserting the Authorization header into them before passing them on to App A.
  • 用户使用他的用户名和密码登录我的 SSO 服务。我使用某种机制对他进行身份验证。
  • 稍后用户想要访问 App A。
    • 用户对 App A 的请求被 SSO 服务拦截。SSO 服务使用 SPNEGO 将用户登录到 App A:
      • SSO 服务访问 App A 网页,得到“WWW-Authenticate: Negotiate”响应
      • SSO 服务代表用户生成“Authorization: Negotiate xxx”响应,响应 App A。用户现在登录到 App A。
    • SSO 服务拦截后续用户对 App A 的请求,将 Authorization 标头插入其中,然后再将它们传递给 App A。

Does that sound right?

听起来对吗?

I need two things (at least that I can think of now):

我需要两件事(至少我现在能想到的):

  • the ability to generate the "Authorization: Negotiate xxx" token on behalf of the user, preferably using Python
  • the ability to validate "Authorization: Negotiate xxx" headers in Python (for a later part of the project)
  • 代表用户生成“授权:协商xxx”令牌的能力,最好使用Python
  • 在 Python 中验证“授权:协商 xxx”标题的能力(用于项目的后期部分)

采纳答案by JimB

This is exactly what Apple does with its Calendar Server. They have a python gssapilibrary for the kerberos part of the process, in order to implement SPNEGO.

这正是 Apple 对其Calendar Server所做的。他们有一个python gssapi库用于进程的 kerberos 部分,以实现SPNEGO

Look in CalendarServer/twistedcaldav/authkerb.py for the server auth portion. The kerberos module (which is a c module), doesn't have any useful docstrings, but PyKerberos/pysrc/kerberos.py has all the function definitions.

在 CalendarServer/twistedcaldav/authkerb.py 中查找服务器身份验证部分。kerberos 模块(即 ac 模块)没有任何有用的文档字符串,但 PyKerberos/pysrc/kerberos.py 具有所有函数定义。

Here's the urls for the svn trunks:
http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk
http://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk

这是 svn 中继的 URL:
http: //svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk
http://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk

回答by Pat Gonzalez

Take a look at the http://spnego.sourceforge.net/credential_delegation.htmltutorial. It seems to be doing what you are trying to do.

查看http://spnego.sourceforge.net/credential_delegation.html教程。它似乎正在做你想做的事情。

回答by Rapsack

I've been searching quite some time for something similar (on Linux), that has lead me to this page several times, yet giving no answer. So here is my solution, I came up with:

我一直在寻找类似的东西(在 Linux 上)已经有一段时间了,这让我多次进入这个页面,但没有给出答案。所以这是我的解决方案,我想出了:

The web-server is a Apache with mod_auth_kerb. It is already running in a Active Directory, single sign-on setup since quite some time. What I was already able to do before:

网络服务器是一个带有 mod_auth_kerb 的 Apache。它已经在 Active Directory 中运行,单点登录设置已经有一段时间了。我之前已经能够做的事情:

  • Using chromium with single sign on on Linux (with a proper krb5 setup, with working kinit user@domain)
  • Having python connect and single sign on using sspi from the pywin32 package, with something like sspi.ClientAuth("Negotiate", targetspn="http/%s" % host)
  • 在 Linux 上使用 Chrome 单点登录(使用正确的 krb5 设置,使用 kinit user@domain)
  • 使用 pywin32 包中的 sspi 进行 python 连接和单点登录,例如 sspi.ClientAuth("Negotiate", targetspn="http/%s" % host)

The following code snippet completes the puzzle (and my needs), having Python single sign on with Kerberos on Linux (using python-gssapi):

以下代码片段完成了这个难题(以及我的需求),在 Linux 上使用 Kerberos 进行 Python 单点登录(使用 python-gssapi):

in_token=base64.b64decode(neg_value)
service_name = gssapi.Name("HTTP@%s" % host, gssapi.C_NT_HOSTBASED_SERVICE)
spnegoMechOid = gssapi.oids.OID.mech_from_string("1.3.6.1.5.5.2")
ctx = gssapi.InitContext(service_name,mech_type=spnegoMechOid)
out_token = ctx.step(in_token)
buffer = sspi.AuthenticationBuffer()
outStr = base64.b64encode(out_token)