Kerberos認証とPython

Windowsで認証にActiveDirectoryを使っている環境だと、シングルサインオン(SSO)などやるときにKerberos認証を使いたいこともあるだろうということで調べていました。

他の認証方法はNTLMがあるけど、非推奨のようなのでKerberosのほうを調べることに。

Kerberosのサーバー実装はOSSでもあるので、開発だとUbuntuだとkrb5-serverなどを使えばよいみたい。

Dockerで手軽に動かせるものを探したところ以下は良さそうだった。

GitHub - gcavalcante8808/docker-krb5-server: A Krb5Server Docker Image very easy and simple to use.

docker-krb5-serverを試す

READMEの通り。docker-composeで起動。

cd tmp
git clone https://github.com/gcavalcante8808/docker-krb5-server.git
cd docker-krb5-server
docker-compose up -d

adminのパスワードは環境変数で指定しない場合は、自動生成されてdockerのログに出力されている。

docker logs dockerkrb5server_kdc_1

クライアント側はkrb5-userをインストールしといて /etc/krb5.conf にREALMの設定をしておく。

[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
default_realm = EXAMPLE.COM

[realms]
EXAMPLE.COM = {
   kdc = localhost
   admin_server = localhost
}

kadminでプリンシパルを追加しとく。

$ kadmin admin/admin@EXAMPLE.com
Authenticating as principal admin/admin@EXAMPLE.COM with password.
Password for admin/admin@EXAMPLE.COM: adminのパスワードを入力
kadmin:  addprinc user01@EXAMPLE.COM
WARNING: no policy specified for user01@EXAMPLE.COM; defaulting to no policy
Enter password for principal "user01@EXAMPLE.COM":
Re-enter password for principal "user01@EXAMPLE.COM":
Principal "user01@EXAMPLE.COM" created.
kadmin:  q

PythonのKerberosモジュールを試す

AppleのcaldavのプロジェクトがPythonのKerberosモジュールを公開していて、PyPIに登録されている。

kerberos 1.2.5 : Python Package Index

Ubuntuだとlibkrb5-devが必要。

パスワードが正しいか試す最小限のコードであればこれぐらい。

import kerberos
user = "user01"
password = "p@ssw0rd"
kerberos.checkPassword(user, password, "localhost", "EXAMPLE.COM")

検証に失敗すると例外が発生する。

シングルサインオン対応のWebアプリ実装に使えそうなモジュール

前段にApacheを置いてもよいのであれば、ApacheモジュールでKerberos認証(mod_kerberosなど)を使って、X-Remote-Userヘッダをアプリケーション側で使う。

Python側でKerberos認証を処理するなら、前述のkerberosモジュールなどを使う。

ちょっと探してみたところ、WSGIミドルウェアだとwsgi-kerberosがよく出来てる感じだった。

GitHub - mkomitee/wsgi-kerberos: WSGI Kerberos Authentication Middleware

Djangoだとdjango-kerberosとdjango-auth-kerberosというのがあった。

django-auth-kerberosは認証バックエンド実装のみなので、シングルサインオンには使えない。

django-kerberosはViewの実装もあり、シングルサインオンにも対応しているが、ライセンスがAGPLなので利用する場合は気をつける必要がある。

wsgi-kerberosを使っとくのが無難かもしれない。

追記

  • SAMLのほうがよいのでは?という指摘頂いた。知識ないので調べてみる。
  • wsgi-kerberosはPython3だと動かない?かも。
  • kerberosのセットアップがシビアな感じがして、いろいろいじってると動かなくなって原因特定が大変な感じ。エラーメッセージだけではどうしようもない。