Autorización de usuario en Django a través de GSSAPI y delegación de derechos de usuario al servidor

Recientemente, mis colegas y yo necesitábamos implementar una autorización transparente (SSO) en nuestro proyecto. Ahora hay bastante información sobre el tema, especialmente en ruso. Por esta razón, se decidió compartir con los descendientes la implementación de dicha funcionalidad.

Entonces, la tarea era la siguiente: era necesario configurar una autorización transparente a través de GSSAPI del usuario al servidor, y también tener la capacidad de ir a la base de datos en nombre de este usuario.

Tuvimos:

  • servidor Kerberos + LDAP configurado
  • Servidor PostgreSQL configurado para autorización exclusivamente por GSSAPI
  • Servidor de aplicaciones Django + UWSGI + nginx con Kerberos configurado

Inicialmente, la idea era delegar la autorización del usuario en la aplicación al servidor web, configurando la autorización GSSAPI en ella, y Django para indicar que trabajaríamos con RemoteUser. Como parte de esta descripción, no hablaré sobre cómo configurar nginx para que funcione en GSSAPI, y Django para delegar la autorización a un servidor web, esta es una parte bien documentada, y hay muchos artículos sobre esto. Después de ajustes y pruebas, nos dimos cuenta de que esto no es absolutamente lo que necesitamos. Sí, podemos autorizar y obtener el nombre principal del usuario, pero no tenemos derechos para hacer nada en nombre de este usuario.

Luego intentamos encontrar algo que valga la pena en Internet. Tuvieron relativamente éxito y se encontraron los siguientes paquetes para Django: django-kerberos , django-auth-spnego , django-auth-kerbero . De hecho, todos estos paquetes hicieron lo mismo, algunos no se actualizaron durante mucho tiempo y tuvieron que "bailar con una pandereta" durante mucho tiempo, por lo que al menos algo funcionó. Proporcionaron la misma funcionalidad que el paquete nginx (GSSAPI) + Django (RemouteUser). Todos ellos ayudaron a resolver el problema con su código fuente.

A continuación, se encontraron los siguientes paquetes para trabajar con GSSAPI en Python: ccs-pykerberos y python-gssapi , de hecho, importan la implementación del estándar RFC2744 y RFC4559 en Python. Usando el paquete ccs-pykerberos, acabamos de implementar la funcionalidad deseada, luego mostraré un pequeño código donde se implementa la comunicación con LDAP y el usuario, así como una consulta a la base de datos en su nombre.

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) 

Primero, debemos verificar si el encabezado de autorización nos fue otorgado; de lo contrario, deberíamos enviar el encabezado con Negotiate en respuesta y nuevamente esperar el token del usuario Negotiate. Este token se ve como una gran tela de pie codificada en base64. Después de recibir el token, inicializamos (autorizamos) el servidor de nuestra aplicación en el servicio LDAP utilizando la función authGSSServerInit (). A continuación, autorizaremos en el servicio LDAP en nombre del usuario, utilizando la función authGSSServerStep () solo para el token que se recibió del encabezado. Luego obtenemos el principal del usuario, que usaremos como usuario, al ejecutar la consulta en la base de datos. Y también, necesitamos crear un caché bitel Kerberos, que se usará automáticamente para autorizarnos en PostgreSQL, la función authGSSServerStoreDelegate (). Esta función solo está disponible en la última versión de este paquete, por lo que debe clonar sus fuentes con git y build.

El navegador debe estar configurado para devolver Negociar, por defecto esta opción está desactivada. Todas las pruebas se realizaron en Firefox en CentOS7, y CentOS7 se instaló en todos los servidores.

Además, podemos tener un problema en el que el caché de tickets generado por nuestra función no será visible para nuestro proceso y, en consecuencia, obtendremos que el usuario no estaba autorizado en GSSAPI. Se resuelve configurando el almacenamiento en caché de tickets en krb5.conf. Por si acaso, daré un ejemplo de nuestra configuración:

/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 #    -    #default_ccache_name = KEYRING:persistent:%{uid} #    KRB5_KTNAME     default_keytab_name = FILE:/etc/httpd/http.keytab [realms] DOMAIN.RU = { kdc = ldap-server-host.domain.ru:88 master_kdc = ldap-server-host.domain.ru:88 admin_server = ldap-server-host.domain.ru:749 kpasswd_server = ldap-server-host.domain.ru:464 default_domain = domain.ru pkinit_anchors = FILE:/etc/domain/ca.crt } [domain_realm] .domain.ru = DOMAIN.RU domain.ru = DOMAIN.RU .domain.ru = DOMAIN.RU 


Este fragmento de código se creó para ayudar a comprender cómo se produce la autorización y la delegación de derechos, luego, con este conocimiento, puede crear decoradores de autorizaciones y vínculos de retroceso de comunicación con la base de datos. El paquete ccs-pykerberos fue desarrollado por Apple para sus necesidades internas, respectivamente, proporcionaré un enlace a su código, donde lo usan. Nos ayudó mucho a comprender que desarrollaron ccs-calendarserver / twistedcaldav / authkerb.py

Enlaces utiles


Source: https://habr.com/ru/post/es427839/


All Articles