Vor kurzem mussten meine Kollegen und ich eine transparente (SSO) Autorisierung in unserem Projekt implementieren. Jetzt gibt es einige Informationen zu diesem Thema, insbesondere auf Russisch. Aus diesem Grund wurde beschlossen, die Implementierung solcher Funktionen mit Nachkommen zu teilen.
Die Aufgabe war also wie folgt: Es war notwendig, eine transparente Autorisierung über GSSAPI vom Benutzer zum Server zu konfigurieren und dann auch die Möglichkeit zu haben, im Namen dieses Benutzers zur Datenbank zu wechseln.
Wir hatten:
- konfigurierter Kerberos + LDAP-Server
- PostgreSQL-Server, der ausschließlich für die Autorisierung durch GSSAPI konfiguriert ist
- Django + UWSGI + Nginx-Anwendungsserver mit konfiguriertem Kerberos
Ursprünglich bestand die Idee darin, die Benutzerautorisierung in der Anwendung an den Webserver zu delegieren, die GSSAPI-Autorisierung darauf einzurichten und Django anzugeben, dass wir mit RemoteUser arbeiten würden. Als Teil dieser Beschreibung werde ich nicht darüber sprechen, wie Nginx für die Arbeit mit GSSAPI konfiguriert wird und Django die Autorisierung an einen Webserver delegiert. Dies ist ein gut dokumentierter Teil, und es gibt viele Artikel dazu. Nach dem Tuning und den Tests haben wir festgestellt, dass dies absolut nicht das ist, was wir brauchen. Ja, wir können den Benutzerprinzipalnamen autorisieren und abrufen, haben jedoch keine Rechte, im Namen dieses Benutzers etwas zu tun.
Dann haben wir versucht, im Internet etwas Wertvolles zu finden. Sie waren relativ erfolgreich und die folgenden Pakete für Django wurden gefunden:
django-kerberos ,
django-auth-spnego ,
django-auth-kerbero . Tatsächlich haben alle diese Pakete das Gleiche getan, einige wurden lange Zeit nicht aktualisiert und mussten lange Zeit "mit einem Tamburin tanzen", damit zumindest etwas funktionierte. Sie boten die gleiche Funktionalität wie das Nginx-Bundle (GSSAPI) + Django (RemouteUser). Alle haben geholfen, das Problem mit ihrem Quellcode zu lösen.
Als nächstes wurden die folgenden Pakete für die Arbeit mit GSSAPI in Python gefunden:
ccs-pykerberos und
python-gssapi . Tatsächlich importieren sie die Implementierung der Standards RFC2744 und RFC4559 in Python. Mit dem Paket ccs-pykerberos haben wir es gerade geschafft, die beabsichtigte Funktionalität zu implementieren. Dann werde ich einen kleinen Code zeigen, in dem die Kommunikation mit LDAP und dem Benutzer implementiert ist, sowie eine Abfrage an die Datenbank in seinem Namen.
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)
Zuerst müssen wir prüfen, ob der Autorisierungsheader an uns übergeben wurde. Wenn nicht, sollten wir den Header mit Negotiate als Antwort senden und erneut auf das Token des Negotiate-Benutzers warten. Dieser Token sieht aus wie ein großes Fußtuch, das in base64 codiert ist. Nach Erhalt des Tokens initialisieren (autorisieren) wir den Server unserer Anwendung im LDAP-Dienst mit der Funktion authGSSServerInit (). Als Nächstes autorisieren wir den LDAP-Dienst im Namen des Benutzers mithilfe der Funktion authGSSServerStep () nur für das Token, das vom Header empfangen wurde. Dann erhalten wir den Principal des Benutzers, den wir als Benutzer verwenden, wenn wir die Abfrage in der Datenbank ausführen. Außerdem müssen wir einen Kerberos-Bitel-Cache erstellen, der automatisch verwendet wird, um uns in PostgreSQL, der authGSSServerStoreDelegate () -Funktion, zu autorisieren. Diese Funktion ist nur in der neuesten Version dieses Pakets verfügbar, daher müssen Sie Ihre Quellen mit git und build klonen.
Der Browser sollte so konfiguriert sein, dass Negotiate zurückgegeben wird. Standardmäßig ist diese Option deaktiviert. Alle Tests wurden unter Firefox in CentOS7 durchgeführt, und CentOS7 wurde auf allen Servern installiert.
Außerdem haben wir möglicherweise ein Problem, bei dem der von unserer Funktion generierte Ticket-Cache für unseren Prozess nicht sichtbar ist und wir dementsprechend feststellen, dass der Benutzer nicht in GSSAPI autorisiert wurde. Es wird gelöst, indem das Ticket-Caching in krb5.conf festgelegt wird. Für alle Fälle gebe ich ein Beispiel für unsere Konfiguration:
/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
Dieser Code wurde erstellt, um zu verstehen, wie die Autorisierung und Delegierung von Rechten erfolgt. Mit diesem Wissen können Sie Autorisierungsdekoratoren und Kommunikations-Backlinks mit der Datenbank erstellen. Das ccs-pykerberos-Paket wurde von Apple für seine internen Anforderungen entwickelt. Ich werde einen Link zu ihrem Code bereitstellen, wo sie ihn verwenden. Er hat uns sehr geholfen zu verstehen, dass sie
ccs-calendarserver / twistedcaldav / authkerb.py entwickelt habenNützliche Links