Python を使用した SSO の SPNEGO (kerberos トークンの生成/検証)
-
06-09-2019 - |
質問
参加サーバーの一部が Windows (IIS) ボックスである単純なシングル サインオン シナリオを実装しようとしています。これには SPNEGO が合理的な方法のようです。
シナリオは次のとおりです。
- ユーザーは、ユーザー名とパスワードを使用して SSO サービスにログインします。何らかのメカニズムを使用して彼を認証します。
- しばらくして、ユーザーはアプリ A にアクセスしたいと考えます。
- アプリ A に対するユーザーのリクエストは、SSO サービスによってインターセプトされます。SSO サービスは SPNEGO を使用してユーザーをアプリ A にログインさせます。
- SSO サービスがアプリ A の Web ページにアクセスし、「WWW-Authenticate:」を取得します。交渉します」との返答
- SSO サービスは「認可:ユーザーに代わって「xxx をネゴシエートします」という応答がアプリ A に応答します。ユーザーはアプリ A にログインしています。
- SSO サービスは、アプリ A に対する後続のユーザー リクエストをインターセプトし、リクエストに Authorization ヘッダーを挿入してからアプリ A に渡します。
- アプリ A に対するユーザーのリクエストは、SSO サービスによってインターセプトされます。SSO サービスは SPNEGO を使用してユーザーをアプリ A にログインさせます。
それは正しいと思いますか?
必要なものは 2 つあります (少なくとも今思いつく限り)。
- 「承認」を生成する機能:できれば Python を使用して、ユーザーに代わって xxx" トークンをネゴシエートします
- 「認可:Python で xxx" ヘッダーをネゴシエートする (プロジェクトの後半部分用)
解決
これは、Appleがその Calendar Serverののとまったく同じものです。彼らは、のpython GSSAPI のライブラリを持っていますhref = "http://www.ietf.org/rfc/rfc4559.txt" のrel = "nofollowをnoreferrer"> SPNEGO の。
サーバーの認証部分のためCalendarServer / twistedcaldav / authkerb.pyでご覧ください。 (Cモジュールである)ケルベロスモジュールは、任意の有用なドキュメンテーション文字列を持っているが、PyKerberos / pysrc / kerberos.pyすべての関数定義を有していません。
ここでのsvnトランクのURLです:
http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk
http://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk
他のヒント
http://spnego.sourceforge.net/credential_delegation.htmlチュートリアル。それはあなたがやろうとしているものをやっているようだ。
私は同様のもの(Linux上で)をかなり長い間検索してきましたが、何度かこのページにたどり着きましたが、まだ答えがありません。そこで、私が思いついた解決策は次のとおりです。
Web サーバーは mod_auth_kerb を備えた Apache です。これは、かなり前から Active Directory のシングル サインオン設定ですでに実行されています。以前にすでにできていたこと:
- Linux でのシングル サインオンでの chromium の使用 (適切な krb5 セットアップ、kinit user@domain の動作)
- pywin32 パッケージの sspi を使用して Python に接続し、シングル サインオンします。
sspi.ClientAuth("Negotiate", targetspn="http/%s" % host)
次のコード スニペットは、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)