How to get started with
Matt Hamilton
The Pluggable
Authentication System
Plone Conference 2013 - Brasilia
Plone Conference 2013 - Brasilia
Who am I?
• Working with Plone/Zope since 1999
• Director at Netsight in the UK
• Worked ...
Plone Conference 2013 - Brasilia
What is PAS?
• Pluggable Authentication System
Plone Conference 2013 - Brasilia
History of PAS
• Zope User Folders
• ExtUserFolder
• PAS
Plone Conference 2013 - Brasilia
PAS is one of Plone’s
Killer Features
Plone Conference 2013 - Brasilia
Plone Conference 2013 - Brasilia
Architecture
• Uses the Zope Component Architecture
(ZCA) heavily
• Many interfaces, each...
Plone Conference 2013 - Brasilia
Anonymoususerfactory Plugins
Create anonymous users.
Authentication Plugins
Authenticatio...
Plone Conference 2013 - Brasilia
Interfaces
class IExtractionPlugin( Interface ):
""" Extracts login name and credentials ...
Plone Conference 2013 - Brasilia
Interfaces
class IAuthenticationPlugin( Interface ):
""" Map credentials to a user ID.
""...
Plone Conference 2013 - Brasilia
Interfaces
class IPropertiesPlugin( Interface ):
""" Return a property set for a user.
""...
Plone Conference 2013 - Brasilia
Interfaces
class IGroupsPlugin( Interface ):
""" Determine the groups to which a user bel...
Plone Conference 2013 - Brasilia
Plugins
• Plugins can be stacked in order you want
them to be used
Plone Conference 2013 - Brasilia
Plugins
Plone Conference 2013 - Brasilia
Example PAS Plugins
• ZODB User Manager
• Products.LDAPMultiPlugins (PloneLDAP)
• pas.plu...
Plone Conference 2013 - Brasilia
Combining PAS Plugins
Plone Conference 2013 - Brasilia
Worked Example
• netsight.aspxauthplugin
• Encrypts/Decrypts the .ASPXAUTH cookie
used by...
Plone Conference 2013 - Brasilia
def extractCredentials( self, request )
“””To extract the cookie from the browser”””
def ...
Plone Conference 2013 - Brasilia
security.declarePrivate( 'extractCredentials' )
def extractCredentials( self, request ):
...
Plone Conference 2013 - Brasilia
security.declarePrivate( 'authenticateCredentials' )
def authenticateCredentials( self, c...
Plone Conference 2013 - Brasilia
# check signature is valid
if not self.checkSignature(data,sig):
return None
# decrypt da...
Plone Conference 2013 - Brasilia
security.declarePrivate( 'resetCredentials' )
def resetCredentials(self, request, respons...
Plone Conference 2013 - Brasilia
Gotchas
• UserId versus Login
• Plugin Performance
• Plugin Order
• Current paster/templa...
Plone Conference 2013 - Brasilia
Obrigado!
Matt Hamilton
matth@netsight.co.uk
@hammertoe
http://slideshare.net/hammertoe
Upcoming SlideShare
Loading in...5
×

How to get started with the Pluggable Authentication System

1,074

Published on

A presentation given at Plone Conference 2013 in Brasilia. This presentation explains Plone's Pluggable Authentication System (PAS) and how to get started with writing your own PAS Plugin.

Published in: Technology, Art & Photos
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,074
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
7
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

How to get started with the Pluggable Authentication System

  1. 1. How to get started with Matt Hamilton The Pluggable Authentication System Plone Conference 2013 - Brasilia
  2. 2. Plone Conference 2013 - Brasilia Who am I? • Working with Plone/Zope since 1999 • Director at Netsight in the UK • Worked on a number of projects doing authentication over the years
  3. 3. Plone Conference 2013 - Brasilia What is PAS? • Pluggable Authentication System
  4. 4. Plone Conference 2013 - Brasilia History of PAS • Zope User Folders • ExtUserFolder • PAS
  5. 5. Plone Conference 2013 - Brasilia PAS is one of Plone’s Killer Features
  6. 6. Plone Conference 2013 - Brasilia
  7. 7. Plone Conference 2013 - Brasilia Architecture • Uses the Zope Component Architecture (ZCA) heavily • Many interfaces, each defining an aspect of the authentication process • Each plugin can implement one or more interfaces
  8. 8. Plone Conference 2013 - Brasilia Anonymoususerfactory Plugins Create anonymous users. Authentication Plugins Authentication plugins are responsible for validating credentials generated by the Extraction Plugin. Challenge Plugins Challenge plugins initiate a challenge to the user to provide credentials. Challenge_Protocol_Chooser Plugins Challenge Protocol Chooser plugins decide what authorizationprotocol to use for a given request type. Reset Credentials Plugins Credential clear plugins respond to a user logging out. Update Credentials Plugins Credential update plugins respond to the user changing credentials. Extraction Plugins Extraction plugins are responsible for extracting credentials from the request. Group_Enumeration Plugins Enumeration plugins allow querying groups by ID. Group_Introspection Plugins Group Introspection provides listings of groups and membership Group_Management Plugins Group Management provides add/write/deletion of groups and member management Groups Plugins Groups plugins determine the groups to which a user belongs. Local_Roles Plugins Defines Policy for getting Local Roles Notcompetent Plugins Not-Competent plugins check whether this user folder should not authenticate the current request. These plugins are not used for a top level user folder. They are typically used to prevent shaddowing of authentications by higher level user folders. Properties Plugins Properties plugins generate property sheets for users. Request_Type_Sniffer Plugins Request Type Sniffer plugins detect the type of an incoming request. Role_Assigner Plugins Role Assigner plugins allow the Pluggable Auth Service to assign roles to principals. Role_Enumeration Plugins Enumeration plugins allow querying roles by ID. Roles Plugins Roles plugins determine the global roles which a user has. Update Plugins Update plugins allow the user or the application to update the user's properties. User_Adder Plugins User Adder plugins allow the Pluggable Auth Service to create users. User_Enumeration Plugins Enumeration plugins allow querying users by ID, and searching for users who match particular criteria. Userfactory Plugins Create users. User_Introspection Plugins The User Introspection plugins allow the Pluggable Auth Service to provide lists of users User_Management Plugins The User Management plugins allow the Pluggable Auth Service to add/delete/modify users Validation Plugins Validation plugins specify allowable values for user properties (e.g., minimum password length, allowed characters, etc.)
  9. 9. Plone Conference 2013 - Brasilia Interfaces class IExtractionPlugin( Interface ): """ Extracts login name and credentials from a request. """ def extractCredentials( request ): """ request -> {...} o Return a mapping of any derived credentials. o Return an empty mapping to indicate that the plugin found no appropriate credentials. """
  10. 10. Plone Conference 2013 - Brasilia Interfaces class IAuthenticationPlugin( Interface ): """ Map credentials to a user ID. """ def authenticateCredentials( credentials ): """ credentials -> (userid, login) o 'credentials' will be a mapping, as returned by IExtractionPlugin. o Return a tuple consisting of user ID (which may be different from the login name) and login o If the credentials cannot be authenticated, return None. """
  11. 11. Plone Conference 2013 - Brasilia Interfaces class IPropertiesPlugin( Interface ): """ Return a property set for a user. """ def getPropertiesForUser( user, request=None ): """ user -> {} o User will implement IPropertiedUser. o Plugin should return a dictionary or an object providing IPropertySheet. o Plugin may scribble on the user, if needed (but must still return a mapping, even if empty). o May assign properties based on values in the REQUEST object, if present """
  12. 12. Plone Conference 2013 - Brasilia Interfaces class IGroupsPlugin( Interface ): """ Determine the groups to which a user belongs. """ def getGroupsForPrincipal( principal, request=None ): """ principal -> ( group_1, ... group_N ) o Return a sequence of group names to which the principal (either a user or another group) belongs. o May assign groups based on values in the REQUEST object, if present """
  13. 13. Plone Conference 2013 - Brasilia Plugins • Plugins can be stacked in order you want them to be used
  14. 14. Plone Conference 2013 - Brasilia Plugins
  15. 15. Plone Conference 2013 - Brasilia Example PAS Plugins • ZODB User Manager • Products.LDAPMultiPlugins (PloneLDAP) • pas.plugins.velruse • netsight.windowsauthplugin • netsight.aspxauthplugin
  16. 16. Plone Conference 2013 - Brasilia Combining PAS Plugins
  17. 17. Plone Conference 2013 - Brasilia Worked Example • netsight.aspxauthplugin • Encrypts/Decrypts the .ASPXAUTH cookie used by .NET applications • Allows Plone to trust the auth of a .NET application and vice-versa • Simplified, ignoring some of the boiler plate and crypto code
  18. 18. Plone Conference 2013 - Brasilia def extractCredentials( self, request ) “””To extract the cookie from the browser””” def authenticateCredentials( self, credentials ) “””To decrypt the cookie and validate it is correct””” def resetCredentials(self, request, response) “””To delete the cookie on logout”””
  19. 19. Plone Conference 2013 - Brasilia security.declarePrivate( 'extractCredentials' ) def extractCredentials( self, request ): """ Extract auth credentials from 'request'. """ cookie = request.cookies.get('.ASPXAUTH') if cookie: creds = {} creds['cookie'] = cookie creds['plugin'] = self.getId() return creds
  20. 20. Plone Conference 2013 - Brasilia security.declarePrivate( 'authenticateCredentials' ) def authenticateCredentials( self, credentials ): request = self.REQUEST response = request.RESPONSE # We only authenticate when our challenge mechanism # extracted the cookie if credentials.get('plugin') != self.getId(): return None cookie = credentials.get('cookie') if not cookie: return None sig, data = self.decodeCookie(cookie)
  21. 21. Plone Conference 2013 - Brasilia # check signature is valid if not self.checkSignature(data,sig): return None # decrypt data decryptedBytes = self.decryptData(data) if not decryptedBytes: return None # unpack the values from the data unpacked = self.unpackData(decryptedBytes) if unpacked is None: return None start_time, end_time, username, version, persistent, userdata, path = unpacked # return the userid and login return username, username
  22. 22. Plone Conference 2013 - Brasilia security.declarePrivate( 'resetCredentials' ) def resetCredentials(self, request, response): """ Raise unauthorized to tell browser to clear credentials. """ response.expireCookie('.ASPXAUTH', path='/', domain='.netsightdev.co.uk')
  23. 23. Plone Conference 2013 - Brasilia Gotchas • UserId versus Login • Plugin Performance • Plugin Order • Current paster/templar template missing (sprint?)
  24. 24. Plone Conference 2013 - Brasilia Obrigado! Matt Hamilton matth@netsight.co.uk @hammertoe http://slideshare.net/hammertoe
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×