Baru-baru ini, kolega saya dan saya perlu menerapkan otorisasi transparan (SSO) dalam proyek kami. Sekarang ada sedikit informasi tentang topik ini, terutama dalam bahasa Rusia. Untuk alasan ini, diputuskan untuk berbagi dengan keturunan implementasi fungsi tersebut.
Jadi tugasnya adalah sebagai berikut: perlu mengkonfigurasi otorisasi transparan melalui GSSAPI dari pengguna ke server, dan kemudian dapat pergi ke database atas nama pengguna ini.
Kami memiliki:
- mengkonfigurasi server Kerberos + LDAP
- Server PostgreSQL dikonfigurasi untuk otorisasi secara eksklusif oleh GSSAPI
- Server aplikasi Django + UWSGI + nginx dengan Kerberos terkonfigurasi
Awalnya, idenya adalah untuk mendelegasikan otorisasi pengguna dalam aplikasi ke server web, menyiapkan otorisasi GSSAPI di atasnya, dan Django untuk menunjukkan bahwa kami akan bekerja dengan RemoteUser. Sebagai bagian dari uraian ini, saya tidak akan berbicara tentang cara mengkonfigurasi nginx agar berfungsi pada GSSAPI, dan Django untuk mendelegasikan otorisasi ke server web, ini adalah bagian yang terdokumentasi dengan baik, dan ada banyak artikel tentang ini. Setelah penyetelan dan pengujian, kami menyadari bahwa ini sama sekali bukan yang kami butuhkan. Ya, kami dapat mengotorisasi dan mendapatkan nama utama pengguna, tetapi kami tidak berhak melakukan apa pun atas nama pengguna ini.
Kemudian kami berusaha menemukan sesuatu yang bermanfaat di Internet. Mereka relatif sukses, dan paket-paket berikut untuk Django ditemukan:
Django-kerberos ,
Django-auth-spnego ,
Django-auth-kerbero . Faktanya, semua paket ini melakukan hal yang sama, beberapa tidak diperbarui untuk waktu yang lama dan harus "menari dengan rebana" untuk waktu yang lama, sehingga setidaknya ada sesuatu yang berhasil. Mereka menyediakan fungsionalitas yang sama dengan bundel nginx (GSSAPI) + Django (RemouteUser). Semua dari mereka membantu menyelesaikan masalah dengan kode sumber mereka.
Selanjutnya, paket-paket berikut ditemukan untuk bekerja dengan GSSAPI di Python:
ccs-pykerberos dan
python-gssapi , bahkan mereka mengimpor implementasi standar RFC2744 dan RFC4559 dalam Python. Menggunakan paket ccs-pykerberos, kami baru saja berhasil mengimplementasikan fungsionalitas yang dimaksud, maka saya akan menunjukkan sedikit kode di mana komunikasi dengan LDAP dan pengguna diimplementasikan, serta permintaan ke database atas namanya.
from django.shortcuts import render from django.template.response import TemplateResponse import kerberos import psycopg2 def index(request): if 'HTTP_AUTHORIZATION' in request.META: kind, initial_client_token = request.META['HTTP_AUTHORIZATION'].split(' ', 1) if kind == 'Negotiate': service = 'HTTP@django-server-pricipal.che.ru' _ignore_result, krb_context = kerberos.authGSSServerInit(service) kerberos.authGSSServerStep(krb_context, initial_client_token) principal = kerberos.authGSSServerUserName(krb_context) _ignore_result = kerberos.authGSSServerStoreDelegate(krb_context) conn = psycopg2.connect( host='postgresql-server-host', user=principal, dbname='request-db', ) cursor = conn.cursor() cursor.execute("SELECT version()") records = cursor.fetchall() else: unauthorized_template_name = 'gssapi_test/unauthorized.html' response = TemplateResponse(request, 'gssapi_test/index.html', status=401) response['WWW-Authenticate'] = 'Negotiate' return response content = {'records': records} return render(request, 'gssapi_test/index.html', content)
Pertama, kita perlu memeriksa apakah header otorisasi diberikan kepada kita, jika tidak, kita harus mengirim header dengan Negosiasi sebagai tanggapan, dan lagi menunggu token dari pengguna Negosiasi. Token ini terlihat seperti kain besar yang disandikan di base64. Setelah menerima token, kami menginisialisasi (mengesahkan) server aplikasi kami di layanan LDAP menggunakan fungsi authGSSServerInit (). Selanjutnya, kami akan mengotorisasi dalam layanan LDAP atas nama pengguna, menggunakan fungsi authGSSServerStep () hanya untuk token yang diterima dari header. Kemudian kita mendapatkan prinsipal dari pengguna, yang akan kita gunakan sebagai pengguna, ketika mengeksekusi query dalam database. Dan juga, kita perlu membuat cache bitel Kerberos, yang akan digunakan secara otomatis untuk mengotorisasi kita di PostgreSQL, fungsi authGSSServerStoreDelegate (). Fungsi ini hanya tersedia dalam versi terbaru dari paket ini, jadi Anda perlu mengkloning sumber Anda dengan git dan build.
Browser harus dikonfigurasi untuk mengembalikan Negosiasi, secara default opsi ini dinonaktifkan. Semua tes dilakukan pada Firefox di CentOS7, dan CentOS7 diinstal pada semua server.
Selain itu, kami mungkin memiliki masalah di mana cache tiket yang dihasilkan oleh fungsi kami tidak akan terlihat oleh proses kami dan, oleh karena itu, kami akan mendapatkan bahwa pengguna tidak diotorisasi di GSSAPI. Ini diselesaikan dengan mengatur caching tiket di krb5.conf. Untuk berjaga-jaga, saya akan memberikan contoh konfigurasi kami:
/etc/krb5.conf includedir /etc/krb5.conf.d/ includedir /var/lib/sss/pubconf/krb5.include.d/ [libdefaults] default_realm = DOMAIN.RU dns_lookup_realm = false dns_lookup_kdc = false rdns = false ticket_lifetime = 24h forwardable = true udp_preference_limit = 0
Sepotong kode ini dibuat untuk membantu memahami bagaimana otorisasi dan pendelegasian hak terjadi, kemudian dengan pengetahuan ini Anda dapat membangun dekorator otorisasi dan backlink komunikasi dengan database. Paket ccs-pykerberos dikembangkan oleh Apple untuk kebutuhan internalnya, masing-masing, saya akan memberikan tautan ke kode mereka, di mana mereka menggunakannya. Dia banyak membantu kami dalam memahami bahwa mereka mengembangkan
ccs-calendarserver / twistedcaldav / authkerb.pyTautan yang bermanfaat