$30 off During Our Annual Pro Sale. View Details »

Introduce Django to your old friends

Introduce Django to your old friends

Leverage Django 1.5’s custom user model to work with corporate/internal authentication networks (Kerberos, Active Directory, LDAP). Associated blog post: http://rogue.ly/circus

Lynn Root

May 17, 2013
Tweet

More Decks by Lynn Root

Other Decks in Programming

Transcript

  1. intentionally left blank

    View Slide

  2. getting django
    to play with
    old friends

    View Slide

  3. getting django
    to play with
    old friends
    or foes

    View Slide

  4. engineer @ red hat
    @roguelynn
    roguelynn.com
    Lynn Root

    View Slide

  5. Lynn Root
    freeipa.org

    View Slide

  6. Lynn Root
    freeipa.org
    IPA != India Pale Ale

    View Slide

  7. Lynn Root
    freeipa.org
    IPA == Identity, Policy, Audit

    View Slide

  8. Lynn Root
    freeipa.org
    IPA == Identity, Policy, Audit
    Alpha

    View Slide

  9. Playbill
    Setting up Custom User
    External Authentication
    External Permissions

    View Slide

  10. rogue.ly/circus

    View Slide

  11. View Slide

  12. Problem:
    Make an internal web app.

    View Slide

  13. Question:
    Can I use Postgres
    for auth?

    View Slide

  14. Crap.
    I have to use single sign-on.

    View Slide

  15. new User models
    +
    antiquated authentication

    View Slide

  16. ZOMG
    new user modelzz !1!!
    what does that mean?

    View Slide

  17. allows custom
    user identifiers

    View Slide

  18. ./manage.py startapp
    synegizerApp

    View Slide

  19. user model:

    View Slide

  20. # synergizerApp/models.py
    from django.contrib.auth.models import AbstractBaseUser
    class KerbUser(AbstractBaseUser):
    username = models.CharField(max_length=254, ...)
    first_name = models.CharField(...)
    last_name = models.CharField(...)
    email = models.EmailField(...)
    synergy_level = models.IntegerField()
    is_team_player = models.BooleanField(default=False)
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email', 'synergy_level']

    View Slide

  21. user manager:

    View Slide

  22. # synergizerApp/models.py
    from django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager)
    class KerbUserManager(BaseUserManager):
    def create_user(self, email, synergy_level,
    password=None):
    user = self.model(email=email,
    synergy_level=synergy_level)
    # <--snip-->
    return user
    def create_superuser(self, email, synergy_level,
    password):
    user = self.create_user(email, synergy_level,
    password=password)
    user.is_team_player = True
    user.save()
    return user

    View Slide

  23. # synergizerApp/models.py
    from django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager)
    ...
    class KerbUser(AbstractBaseUser):
    # <--snip-->
    objects = KerbUserManager()

    View Slide

  24. settings.py

    View Slide

  25. # settings.py
    AUTH_USER_MODEL = 'synergizerApp.KerbUser'
    MIDDLEWARE_CLASSES = (
    ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    ...
    )
    AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.RemoteUserBackends',
    )
    team player!

    View Slide

  26. pointyhairedboss@
    STRATEGERY.COM

    View Slide

  27. pointyhairedboss@
    STRATEGERY.COM

    View Slide

  28. client-centric!!1!
    # synergizerApp/krb5.py
    from django.contrib.auth.backends import (
    RemoteUserBackend)
    class Krb5RemoteUserBackend(RemoteUserBackend):
    def clean_username(self, username):
    # remove @REALM from username
    return username.split("@")[0]

    View Slide

  29. # settings.py
    AUTH_USER_MODEL = 'synergizerApp.KerbUser'
    MIDDLEWARE_CLASSES = (
    ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    ...
    )
    AUTHENTICATION_BACKENDS = (
    'synergizerApp.krb5.Krb5RemoteUserBackend',
    )
    a streamlining team player!

    View Slide

  30. how do I
    Apache?

    View Slide

  31. environment:
    Kerberos + Apache

    View Slide

  32. # /etc/httpd/conf.d/remote_user.conf
    LoadModule auth_kerb_module modules/mod_auth_kerb.so

    AuthName "DjangoConKerberos"
    AuthType Kerberos
    KrbMethodNegotiate On
    KrbMethodK5Passwd Off
    KrbServiceName HTTP/djangocon.rootcloud.com
    KrbAuthRealms ROOTCLOUD.COM
    Krb5KeyTab /etc/http.keytab
    Require valid-user
    Order Deny,Allow
    Deny from all
    Satisfy any

    View Slide

  33. # /etc/httpd/conf.d/remote_user.conf
    LoadModule auth_kerb_module modules/mod_auth_kerb.so

    AuthName "DjangoConKerberos"
    AuthType Kerberos
    KrbMethodNegotiate On
    KrbMethodK5Passwd Off
    KrbServiceName HTTP/djangocon.rootcloud.com
    KrbAuthRealms ROOTCLOUD.COM
    Krb5KeyTab /etc/http.keytab
    Require valid-user
    Order Deny,Allow
    Deny from all
    Satisfy any

    View Slide

  34. # /etc/httpd/conf.d/remote_user.conf
    LoadModule auth_kerb_module modules/mod_auth_kerb.so

    AuthName "DjangoConKerberos"
    AuthType Kerberos
    KrbMethodNegotiate On
    KrbMethodK5Passwd Off
    KrbServiceName HTTP/djangocon.rootcloud.com
    KrbAuthRealms ROOTCLOUD.COM
    Krb5KeyTab /etc/http.keytab
    Require valid-user
    Order Deny,Allow
    Deny from all
    Satisfy any

    View Slide

  35. mod_auth_kerb
    Enrolled host + service
    chown apache

    View Slide

  36. # /etc/httpd/conf.d/remote_user.conf
    LoadModule auth_kerb_module modules/mod_auth_kerb.so

    AuthName "DjangoConKerberos"
    AuthType Kerberos
    KrbMethodNegotiate On
    KrbMethodK5Passwd Off
    KrbServiceName HTTP/djangocon.rootcloud.com
    KrbAuthRealms ROOTCLOUD.COM
    Krb5KeyTab /etc/http.keytab
    Require valid-user
    Order Deny,Allow
    Deny from all
    Satisfy any

    View Slide

  37. does it negotiate?

    View Slide

  38. cURL
    requests.py
    browsers

    View Slide

  39. $ curl --negotiate
    -u : $FQDN

    View Slide

  40. [vagrant@client]# kinit roguelynn
    Password for [email protected]:
    [vagrant@client]# curl -I --negotiate -u : \
    https://synergizeapp.strategery.com
    HTTP/1.1 401 Unauthorized
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate
    Content-type text/html; charset=iso-8859-1
    HTTP/1.1 200
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate sOmE_RanDom_T0k3n

    View Slide

  41. [vagrant@client]# kinit roguelynn
    Password for [email protected]:
    [vagrant@client]# curl -I --negotiate -u : \
    https://synergizeapp.strategery.com
    HTTP/1.1 401 Unauthorized
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate
    Content-type text/html; charset=iso-8859-1
    HTTP/1.1 200
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate sOmE_RanDom_T0k3n

    View Slide

  42. [vagrant@client]# kinit roguelynn
    Password for [email protected]:
    [vagrant@client]# curl -I --negotiate -u : \
    https://synergizeapp.strategery.com
    HTTP/1.1 401 Unauthorized
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate
    Content-type text/html; charset=iso-8859-1
    HTTP/1.1 200
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate sOmE_RanDom_T0k3n
    ticket cache

    View Slide

  43. [vagrant@client]# kinit roguelynn
    Password for [email protected]:
    [vagrant@client]# curl -I --negotiate -u : \
    https://synergizeapp.strategery.com
    HTTP/1.1 401 Unauthorized
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate
    Content-type text/html; charset=iso-8859-1
    HTTP/1.1 200
    Date: Wed, 15 May 2013 09:10:18 GMT
    Server: Apache/2.4.4 (Fedora)
    WWW-Authenticate: Negotiate sOmE_RanDom_T0k3n
    two responses

    View Slide

  44. cURL
    requests.py
    browsers

    View Slide

  45. authentication
    vs
    authorization

    View Slide

  46. authentication
    vs
    authorization

    View Slide

  47. accessing permissions

    View Slide

  48. is user a member of
    “admins”, or
    “team players”, or
    “movers and shakers”, ...

    View Slide

  49. your own
    kerberos environment

    View Slide

  50. Crap.
    Now I’m the point person
    for this.

    View Slide

  51. rogue.ly/circus
    @roguelynn

    View Slide

  52. Background image:
    http://www.animalhi.com/Mammals/elephants/
    abstract_flying_elephants_circus_simplistic_simple_1920x1080_wallpaper_29579

    View Slide