Upgrade to Pro — share decks privately, control downloads, hide ads and more …

EuroPython 2013: Introduce Django to your old friends

EuroPython 2013: Introduce Django to your old friends

Django 1.5 introduced a configurable User model, fantastic! Now what? With the increased flexibility of user models, integrating Django into an existing infrastructure is now easier than ever.

This talk gives an introduction to the new configurable User model, and then walks through how to integrate Django applications to authenticate against already existing identity management systems like LDAP, Kerberos, etc.

8c5e76dca74a59822dbf7f0286177ddd?s=128

Lynn Root

July 03, 2013
Tweet

More Decks by Lynn Root

Other Decks in Programming

Transcript

  1. intentionally left blank Tuesday, July 2, 13

  2. getting django to play with old friends Tuesday, July 2,

    13
  3. getting django to play with old friends or foes Tuesday,

    July 2, 13
  4. Red Hat | @ roguelynn | roguelynn.com Lynn Root River

    Bar, 2013 Tuesday, July 2, 13
  5. Lynn Root freeipa.org Tuesday, July 2, 13

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

    2, 13
  7. Lynn Root freeipa.org IPA == Identity, Policy, Audit Tuesday, July

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

    July 2, 13
  9. Playbill ELI5: Kerberos Setting up Custom User External Authentication External

    Permissions Tuesday, July 2, 13
  10. rogue.ly/kerberos Tuesday, July 2, 13

  11. Tuesday, July 2, 13

  12. Problem: Make an internal web app. Tuesday, July 2, 13

  13. Question: Can I use Postgres for auth? Tuesday, July 2,

    13
  14. Crap. I have to use single sign-on. Tuesday, July 2,

    13
  15. ELI-5: Kerberos Tuesday, July 2, 13

  16. 5-year-old you Tuesday, July 2, 13

  17. who wants to play games Tuesday, July 2, 13

  18. but you must ask Dad for $$ Tuesday, July 2,

    13
  19. so you can buy a ticket to play Tuesday, July

    2, 13
  20. so Dad gives you a few bucks Tuesday, July 2,

    13
  21. and you go to the clerk to buy a ticket

    to play Tuesday, July 2, 13
  22. your money is good, so the clerk gives you a

    ticket for the game Tuesday, July 2, 13
  23. a ticket that only you can use Tuesday, July 2,

    13
  24. because ticket as some super secret special DNA/fingerprint tech Tuesday,

    July 2, 13
  25. now you can play! Tuesday, July 2, 13

  26. (until your money runs out) Tuesday, July 2, 13

  27. ELI-25: Kerberos • protocol for authentication • based on tickets

    and keytabs • avoids sending passwords over the internetz • symmetric-key crypto Tuesday, July 2, 13
  28. Authentication Server Ticket Granting Server Key Distribution Center Kerberos Realm

    HTTP service You KDC Clients Tuesday, July 2, 13
  29. your ID, Ticket Granting Server ID, IP address, lifetime You

    Authentication Server plaintext request Tuesday, July 2, 13
  30. user ID lookup in KDC You Authentication Server Tuesday, July

    2, 13
  31. Ticket Granting Server Session Key Ticket Granting Ticket HTTP service’s

    ID, timestamp, lifetime, TGS Session Key your ID, HTTP service ID, IP address, timestamp, lifetime, and the TGS Session Key You Authentication Server Tuesday, July 2, 13
  32. Ticket Granting Server Session Key Ticket Granting Ticket Your Secret

    Key Ticket Granting Server Secret Key You Authentication Server Tuesday, July 2, 13
  33. Authenticator Ticket Granting Ticket your ID and timestamp your ID,

    HTTP service ID, IP address, timestamp, lifetime, and the TGS Session Key You HTTP Service ID and lifetime plaintext request Ticket Granting Server Tuesday, July 2, 13
  34. You HTTP service lookup in KDC Ticket Granting Server Tuesday,

    July 2, 13
  35. Authenticator Ticket Granting Ticket Ticket Granting Server Secret Key Ticket

    Granting Server Session Key You Ticket Granting Server plaintext request Tuesday, July 2, 13
  36. HTTP Service Session Key Ticket for HTTP Service your client

    ID and timestamp You Ticket Granting Server your ID, HTTP service ID, IP address, timestamp, lifetime, and the TGS Session Key Tuesday, July 2, 13
  37. HTTP Service Session Key Ticket for HTTP Service HTTP Service

    Secret Key Ticket Granting Server Session Key You Ticket Granting Server Tuesday, July 2, 13
  38. Ticket for HTTP Service your ID, HTTP service ID, IP

    address, timestamp, lifetime, and the TGS Session Key Authenticator your client ID and timestamp HTTP service You Tuesday, July 2, 13
  39. Authenticator HTTP Service Secret Key HTTP Service Session Key HTTP

    service You Ticket for HTTP Service Tuesday, July 2, 13
  40. Authenticator HTTP service ID and timestamp You HTTP service Tuesday,

    July 2, 13
  41. Authenticator You HTTP service HTTP Service Session Key Tuesday, July

    2, 13
  42. You HTTP service Tuesday, July 2, 13

  43. how can Django play with Kerberos? Tuesday, July 2, 13

  44. leveraging new User models + antiquated authentication Tuesday, July 2,

    13
  45. ZOMG new user modelzz !1!! what does that mean? Tuesday,

    July 2, 13
  46. allows custom user identifiers Tuesday, July 2, 13

  47. ./manage.py startapp synegizerApp Tuesday, July 2, 13

  48. user model: Tuesday, July 2, 13

  49. # 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'] Tuesday, July 2, 13
  50. user manager: Tuesday, July 2, 13

  51. # 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 Tuesday, July 2, 13
  52. # synergizerApp/models.py from django.contrib.auth.models import ( AbstractBaseUser, BaseUserManager) ... class

    KerbUser(AbstractBaseUser): # <--snip--> objects = KerbUserManager() Tuesday, July 2, 13
  53. settings.py Tuesday, July 2, 13

  54. # 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! Tuesday, July 2, 13
  55. pointyhairedboss@ STRATEGERY.COM Tuesday, July 2, 13

  56. pointyhairedboss@ STRATEGERY.COM Tuesday, July 2, 13

  57. 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] Within Django App Tuesday, July 2, 13
  58. # 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! Tuesday, July 2, 13
  59. Within Apache # /etc/httpd/conf.d/remote_user.conf <Location /> AuthType Kerberos # <--snip-->

    KrbLocalUserMapping On # <--snip--> </Location> Tuesday, July 2, 13
  60. Accessing the user Tuesday, July 2, 13

  61. HTTP Request HTTP Response Even more Middleware AuthenticationMiddleware Some more

    Middleware Some Middleware Django view functions Tuesday, July 2, 13
  62. HTTP Request HTTP Response Even more Middleware RemoteUserMiddleware Some more

    Middleware Some Middleware Django view functions Tuesday, July 2, 13
  63. Accessing user user = request.META["REMOTE_USER"] Tuesday, July 2, 13

  64. Accessing user user = request.META["REMOTE_USER"] pointyhairedboss Tuesday, July 2, 13

  65. how do I Apache? Tuesday, July 2, 13

  66. environment: Kerberos + Apache Tuesday, July 2, 13

  67. # /etc/httpd/conf.d/remote_user.conf LoadModule auth_kerb_module modules/mod_auth_kerb.so <Location /> AuthName "RiverBarKerberos" AuthType

    Kerberos KrbMethodNegotiate On KrbMethodK5Passwd Off KrbLocalUserMapping On KrbServiceName HTTP/riverbar.rootcloud.com KrbAuthRealms ROOTCLOUD.COM Krb5KeyTab /etc/http.keytab Require valid-user Order Deny,Allow Deny from all Satisfy any </Location> Tuesday, July 2, 13
  68. # /etc/httpd/conf.d/remote_user.conf LoadModule auth_kerb_module modules/mod_auth_kerb.so <Location /> AuthName "RiverBarKerberos" AuthType

    Kerberos KrbMethodNegotiate On KrbMethodK5Passwd Off KrbLocalUserMapping On KrbServiceName HTTP/riverbar.rootcloud.com KrbAuthRealms ROOTCLOUD.COM Krb5KeyTab /etc/http.keytab Require valid-user Order Deny,Allow Deny from all Satisfy any </Location> Tuesday, July 2, 13
  69. # /etc/httpd/conf.d/remote_user.conf LoadModule auth_kerb_module modules/mod_auth_kerb.so <Location /> AuthName "RiverBarKerberos" AuthType

    Kerberos KrbMethodNegotiate On KrbMethodK5Passwd Off KrbLocalUserMapping On KrbServiceName HTTP/riverbar.rootcloud.com KrbAuthRealms ROOTCLOUD.COM Krb5KeyTab /etc/http.keytab Require valid-user Order Deny,Allow Deny from all Satisfy any </Location> Tuesday, July 2, 13
  70. mod_auth_kerb Enrolled host + service chown apache Tuesday, July 2,

    13
  71. # /etc/httpd/conf.d/remote_user.conf LoadModule auth_kerb_module modules/mod_auth_kerb.so <Location /> AuthName "RiverBarKerberos" AuthType

    Kerberos KrbMethodNegotiate On KrbMethodK5Passwd Off KrbLocalUserMapping On KrbServiceName HTTP/riverbar.rootcloud.com KrbAuthRealms ROOTCLOUD.COM Krb5KeyTab /etc/http.keytab Require valid-user Order Deny,Allow Deny from all Satisfy any </Location> Tuesday, July 2, 13
  72. # /etc/httpd/conf.d/remote_user.conf LoadModule auth_kerb_module modules/mod_auth_kerb.so <Location /> AuthName "RiverBarKerberos" AuthType

    Kerberos KrbMethodNegotiate On KrbMethodK5Passwd Off KrbLocalUserMapping On KrbServiceName HTTP/riverbar.rootcloud.com KrbAuthRealms ROOTCLOUD.COM Krb5KeyTab /etc/http.keytab Require valid-user Order Deny,Allow Deny from all Satisfy any </Location> Tuesday, July 2, 13
  73. # /etc/httpd/conf.d/remote_user.conf LoadModule auth_kerb_module modules/mod_auth_kerb.so <Location /> AuthName "RiverBarKerberos" AuthType

    Kerberos KrbMethodNegotiate On KrbMethodK5Passwd Off KrbLocalUserMapping On KrbServiceName HTTP/riverbar.rootcloud.com KrbAuthRealms ROOTCLOUD.COM Krb5KeyTab /etc/http.keytab Require valid-user Order Deny,Allow Deny from all Satisfy any </Location> Tuesday, July 2, 13
  74. does it negotiate? Tuesday, July 2, 13

  75. cURL requests.py browsers Tuesday, July 2, 13

  76. $ curl --negotiate -u : $FQDN Tuesday, July 2, 13

  77. [vagrant@client]# kinit roguelynn Password for roguelynn@ROOTCLOUD.COM: [vagrant@client]# klist Ticket cache:

    DIR::/run/user/1000/krb5cc/tktkPmrOq Default principal: roguelynn@ROOTCLOUD.COM Valid starting Expires 06/16/2013 02:02:21 06/17/2013 02:02:18 Service principal krbtgt/ROOTCLOUD.COM@ROOTCLOUD.COM Tuesday, July 2, 13
  78. [vagrant@client]# kinit roguelynn Password for roguelynn@ROOTCLOUD.COM: [vagrant@client]# klist Ticket cache:

    DIR::/run/user/1000/krb5cc/tktkPmrOq Default principal: roguelynn@ROOTCLOUD.COM Valid starting Expires 06/16/2013 02:02:21 06/17/2013 02:02:18 Service principal krbtgt/ROOTCLOUD.COM@ROOTCLOUD.COM Tuesday, July 2, 13
  79. [vagrant@client]# kinit roguelynn Password for roguelynn@ROOTCLOUD.COM: [vagrant@client]# klist Ticket cache:

    DIR::/run/user/1000/krb5cc/tktkPmrOq Default principal: roguelynn@ROOTCLOUD.COM Valid starting Expires 06/16/2013 02:02:21 06/17/2013 02:02:18 Service principal krbtgt/ROOTCLOUD.COM@ROOTCLOUD.COM Tuesday, July 2, 13
  80. [vagrant@client]# kinit roguelynn Password for roguelynn@ROOTCLOUD.COM: [vagrant@client]# klist Ticket cache:

    DIR::/run/user/1000/krb5cc/tktkPmrOq Default principal: roguelynn@ROOTCLOUD.COM Valid starting Expires 06/16/2013 02:02:21 06/17/2013 02:02:18 Service principal krbtgt/ROOTCLOUD.COM@ROOTCLOUD.COM Tuesday, July 2, 13
  81. [vagrant@client]# kinit roguelynn Password for roguelynn@ROOTCLOUD.COM: [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 Tuesday, July 2, 13
  82. [vagrant@client]# kinit roguelynn Password for roguelynn@ROOTCLOUD.COM: [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 Tuesday, July 2, 13
  83. [vagrant@client]# kinit roguelynn Password for roguelynn@ROOTCLOUD.COM: [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 Tuesday, July 2, 13
  84. [vagrant@client]# klist Ticket cache: DIR::/run/user/1000/krb5cc/tktkPmrOq Default principal: roguelynn@ROOTCLOUD.COM Valid starting

    Expires 06/16/2013 02:02:21 06/17/2013 02:02:18 06/16/2013 02:02:21 06/17/2013 02:02:18 Service principal krbtgt/ROOTCLOUD.COM@ROOTCLOUD.COM HTTP/riverbar.rootcloud.com@ROOTCLOUD.COM ticket for HTTP service Tuesday, July 2, 13
  85. cURL requests.py browsers Tuesday, July 2, 13

  86. authentication vs authorization Tuesday, July 2, 13

  87. authentication vs authorization Tuesday, July 2, 13

  88. accessing permissions Tuesday, July 2, 13

  89. accessing permissions • Connecting to LDAP • Calling system commands

    • PAM stack + Apache modules: • mod_auth_kerb • mod_authnz_external Tuesday, July 2, 13
  90. LDAP is user a member of “admins”, or “team players”,

    or “movers and shakers”, ... Tuesday, July 2, 13
  91. getxxx system calls: SSSD • e.g. getent group $USER •

    conveniently accesses group information stored in IPA LDAP • Python wrapper: getent package Tuesday, July 2, 13
  92. Apache modules • mod_auth_kerb for authentication • mod_authnz_external + pwauth

    to defer to PAM for group lookup • pwauth will need a bit of a hack to accept Kerb auth Tuesday, July 2, 13
  93. your own kerberos test environment: rogue.ly/kerberos Tuesday, July 2, 13

  94. word of caution: do NOT install IPA on your local

    machine! Tuesday, July 2, 13
  95. In review • custom user model with SSO • integrate

    Django apps with SSO • access permissions for your app Tuesday, July 2, 13
  96. Crap. Now I’m the point person for this. Tuesday, July

    2, 13
  97. rogue.ly/kerberos @roguelynn Tuesday, July 2, 13

  98. Background image: http://www.animalhi.com/Mammals/elephants/ abstract_flying_elephants_circus_simplistic_simple_1920x1080_wallpaper_29579 Tuesday, July 2, 13