Authentication using REMOTE_USER

Αυτό το άρθρο περιγράφει πως μπορείτε να χρησιμοποιήσετε εξωτερικές πηγές πιστοποίησης (όπου ο Web server έχει ορίσει ως environment variable το REMOTE_USER) μέσα στις Django εφαρμογές σας. Αυτού του είδους η λύση σχετικά με την πιστοποίηση εμφανίζεται, συνήθως, μέσα σε intranet σελίδες, όπου η είσοδος του χρήστη στο σύστημα γίνεται με single sign-on μέσω IIS και του Integrated Windows Authentication ή μέσω Apache και mod_authnz_ldap, CAS, Cosign, WebAuth, mod_auth_sspi, κλπ.

Όταν ο Web server αναλαμβάνει την πιστοποίηση, στην ουσία θέτει τη μεταβλητή REMOTE_USER ως environment variable για να χρησιμοποιηθεί από την εκάστοτε εφαρμογή. Στο Django, η μεταβλητή REMOTE_USER είναι διαθέσιμη μέσα από το attribute request.META του request object. Το Django μπορεί να παραμετροποιηθεί για να κάνει χρήση της μεταβλητής REMOTE_USER χρησιμοποιώντας τη RemoteUserMiddleware ή τη PersistentRemoteUserMiddleware και την κλάση RemoteUserBackend που βρίσκεται μέσα στο module django.contrib.auth.

Παραμετροποίηση

Πρώτα πρέπει να προσθέσετε τη middleware κλάση django.contrib.auth.middleware.RemoteUserMiddleware στη ρύθμιση MIDDLEWARE μετά τη middleware κλάση django.contrib.auth.middleware.AuthenticationMiddleware:

MIDDLEWARE = [
    '...',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    '...',
]

Κατόπιν, πρέπει να αντικαταστήσετε την κλάση ModelBackend με την RemoteUserBackend μέσα στη ρύθμιση AUTHENTICATION_BACKENDS:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.RemoteUserBackend',
]

Με αυτές τις ρυθμίσεις, η RemoteUserMiddleware θα ανιχνεύσει το username μέσα στο request.META['REMOTE_USER'] και όχι μόνο θα πιστοποιήσει αλλά και θα εισάγει αυτόν τον χρήστη αυτόματα στο σύστημα, χρησιμοποιώντας την κλάση RemoteUserBackend.

Ιδιαίτερη προσοχή πρέπει να δοθεί στο γεγονός ότι η ανωτέρω συγκεκριμένη ρύθμιση απενεργοποιεί την πιστοποίηση του, προεπιλεγμένου, ModelBackend. Αυτό σημαίνει ότι αν η τιμή της μεταβλητής REMOTE_USER δεν έχει οριστεί, τότε ο χρήστης δεν θα μπορεί να κάνει log in στο σύστημα, ακόμη και αν χρησιμοποιεί το interface του Django admin. Για την επίλυση αυτού, απλώς προσθέστε το 'django.contrib.auth.backends.ModelBackend' στη λίστα AUTHENTICATION_BACKENDS. Με αυτό τον τρόπο το Django θα χρησιμοποιήσει το ModelBackend ως fallback αν το REMOTE_USER δεν έχει οριστεί.

Η διαχείριση των χρηστών του Django, όπως τα views μέσα στο contrib.admin και η εντολή createsuperuser, δεν δουλεύουν με τους απομακρυσμένους χρήστες (remote users). Αυτά τα interfaces δουλεύουν με τους χρήστες οι οποίοι είναι αποθηκευμένοι στην βάση δεδομένων ανεξαρτήτως της ρύθμισης AUTHENTICATION_BACKENDS.

Σημείωση

Επειδή η κλάση RemoteUserBackend κληρονομεί από την ModelBackend, θα έχετε στην διάθεση σας όλο το API, που είναι υλοποιημένο στο ModelBackend και αφορά τον έλεγχο δικαιωμάτων των χρηστών.

Οι χρήστες με το attribute is_active=False δεν θα τους επιτραπεί να πιστοποιηθούν. Για να το παρακάμψετε αυτό χρησιμοποιήστε την κλάση AllowAllUsersRemoteUserBackend.

Changed in Django 1.10:

Σε παλαιότερες εκδόσεις, οι απενεργοποιημένοι χρήστες δεν απορριπτόντουσαν όπως περιγράφηκε παραπάνω.

Οι χρήστες με το attribute is_active=False δεν θα τους επιτραπεί να πιστοποιηθούν. Για να το παρακάμψετε αυτό χρησιμοποιήστε την κλάση AllowAllUsersRemoteUserBackend.

from django.contrib.auth.middleware import RemoteUserMiddleware

class CustomHeaderMiddleware(RemoteUserMiddleware):
    header = 'HTTP_AUTHUSER'

Προειδοποίηση

Να είστε εξαιρετικά προσεκτικοί όταν χρησιμοποιείτε κάποια subclass της RemoteUserMiddleware η οποία ορίζει δικό της HTTP header. Πρέπει να είστε σίγουροι ότι ο front-end web server ορίζει ή αφαιρεί πάντα αυτόν τον header βασιζόμενος στους κατάλληλους ελέγχους πιστοποίησης. Ποτέ να μην επιτρέπετε στον τελικό χρήστη να μπορεί να καταθέτει ψεύτικες (ή «πλαστογραφημένες») τιμές του header. Εφόσον οι HTTP headers, π.χ X-Auth-User και X-Auth_User ομαλοποιούνται και οι δύο στο κλειδί HTTP_X_AUTH_USER του request.META, θα πρέπει, επίσης, να ελέγξετε ότι ο web server σας δεν επιτρέπει πλαστογραφημένους headers οι οποίοι χρησιμοποιούν κάτω παύλες (“_”) αντί σκέτων παυλών (“-”).

Η παραπάνω προειδοποίηση δεν αφορά μόνο την κλάση RemoteUserMiddleware με τις προεπιλεγμένες της ρυθμίσεις (header = 'REMOTE_USER'), αφού ένα κλειδί που το όνομα του δεν ξεκινά με το HTTP_ μέσα στο request.META, μπορεί να οριστεί μόνο από τον WSGI server σας και όχι απ’ ευθείας από ένα HTTP request header.

Αν χρειάζεστε περισσότερο έλεγχο, μπορείτε να δημιουργήσετε το δικό σας backend πιστοποίησης ο οποίος θα κληρονομεί από την κλάση RemoteUserBackend και θα παρακάμπτει (override) ένα ή περισσότερα από τα attributes και τις μεθόδους της.

Χρήση του REMOTE_USER μόνο στις σελίδες login

Η middleware πιστοποίησης RemoteUserMiddleware προϋποθέτει ότι ο HTTP request header REMOTE_USER υφίσταται με όλα τα πιστοποιημένα requests. Αυτό μπορεί να είναι πρακτικό και να λειτουργεί περίφημα όταν χρησιμοποιούνται απλοί μηχανισμοί HTTP πιστοποίησης όπως o htpasswd, αλλά με άλλες μεθόδους ευαίσθητων πηγών όπως η Negotiate (GSSAPI/Kerberos), η πιστοποίηση στον front-end HTTP server συνήθως ρυθμίζεται για ένα ή για μερικά login URLs και κατόπιν επιτυχούς πιστοποίησης, η εφαρμογή υποτίθεται ότι διατηρεί το πιστοποιημένο session κατά τη διάρκεια της επικοινωνίας.

Η middleware κλάση PersistentRemoteUserMiddleware παρέχει υποστήριξη για αυτήν ακριβώς την περίπτωση. Θα διατηρήσει το πιστοποιημένο session μέχρις ότου ο χρήστης κάνει logout ο ίδιος. Η κλάση μπορεί να χρησιμοποιηθεί ως αντικατάσταση της RemoteUserMiddleware όπως αναφέρθηκε παραπάνω.

Back to Top