how to get started with the pluggable authentication system

24
How to get started with Matt Hamilton The Pluggable Authentication System Plone Conference 2013 - Brasilia

Upload: matt-hamilton

Post on 08-May-2015

981 views

Category:

Technology


3 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: How to get started with the Pluggable Authentication System

How to get started with

Matt Hamilton

The Pluggable Authentication System

Plone Conference 2013 - Brasilia

Page 2: How to get started with the Pluggable Authentication System

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

Page 3: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

What is PAS?

• Pluggable Authentication System

Page 4: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

History of PAS

• Zope User Folders

• ExtUserFolder

• PAS

Page 5: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

PAS is one of Plone’s Killer Features

Page 6: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Page 7: How to get started with the Pluggable Authentication System

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

Page 8: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Anonymoususerfactory PluginsCreate anonymous users.Authentication PluginsAuthentication plugins are responsible for validating credentials generated by the Extraction Plugin.Challenge PluginsChallenge plugins initiate a challenge to the user to provide credentials.Challenge_Protocol_Chooser PluginsChallenge Protocol Chooser plugins decide what authorizationprotocol to use for a given request type.Reset Credentials PluginsCredential clear plugins respond to a user logging out.Update Credentials PluginsCredential update plugins respond to the user changing credentials.Extraction PluginsExtraction plugins are responsible for extracting credentials from the request.Group_Enumeration PluginsEnumeration plugins allow querying groups by ID.Group_Introspection PluginsGroup Introspection provides listings of groups and membershipGroup_Management PluginsGroup Management provides add/write/deletion of groups and member managementGroups PluginsGroups plugins determine the groups to which a user belongs.Local_Roles PluginsDefines Policy for getting Local RolesNotcompetent PluginsNot-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 PluginsProperties plugins generate property sheets for users.Request_Type_Sniffer PluginsRequest Type Sniffer plugins detect the type of an incoming request.Role_Assigner PluginsRole Assigner plugins allow the Pluggable Auth Service to assign roles to principals.Role_Enumeration PluginsEnumeration plugins allow querying roles by ID.Roles PluginsRoles plugins determine the global roles which a user has.Update PluginsUpdate plugins allow the user or the application to update the user's properties.User_Adder PluginsUser Adder plugins allow the Pluggable Auth Service to create users.User_Enumeration PluginsEnumeration plugins allow querying users by ID, and searching for users who match particular criteria.Userfactory PluginsCreate users.User_Introspection PluginsThe User Introspection plugins allow the Pluggable Auth Service to provide lists of usersUser_Management PluginsThe User Management plugins allow the Pluggable Auth Service to add/delete/modify usersValidation PluginsValidation plugins specify allowable values for user properties (e.g., minimum password length, allowed characters, etc.)

Page 9: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Interfacesclass 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. """

Page 10: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Interfacesclass 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. """

Page 11: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Interfacesclass 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 """

Page 12: How to get started with the Pluggable Authentication System

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 """

Page 13: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Plugins

• Plugins can be stacked in order you want them to be used

Page 14: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Plugins

Page 15: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Example PAS Plugins

• ZODB User Manager

• Products.LDAPMultiPlugins (PloneLDAP)

• pas.plugins.velruse

• netsight.windowsauthplugin

• netsight.aspxauthplugin

Page 16: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Combining PAS Plugins

Page 17: How to get started with the Pluggable Authentication System

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

Page 18: How to get started with the Pluggable Authentication System

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”””

Page 19: How to get started with the Pluggable Authentication System

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

Page 20: How to get started with the Pluggable Authentication System

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)

Page 21: How to get started with the Pluggable Authentication System

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

Page 22: How to get started with the Pluggable Authentication System

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')

Page 23: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Gotchas

• UserId versus Login

• Plugin Performance

• Plugin Order

• Current paster/templar template missing (sprint?)

Page 24: How to get started with the Pluggable Authentication System

Plone Conference 2013 - Brasilia

Obrigado!Matt Hamilton

[email protected]

@hammertoe

http://slideshare.net/hammertoe