openid2rp is a Python library to implement OpenID 2.0 Relying Parties (RP). The RP itself will be a web application, and needs to implement all user interface, as well as to provide storage for certain persistent data. The assumption is that the web application has its own management of user accounts already, so OpenID will merely provide convenience for end users who wish to use their OpenID with the web application.
The following three scenarios need to be considered:
* an existing user logs in with an OpenID already known to the application.
* an existing user wants to add an OpenID to his account. The recommended procedure is to let the user first log in regularly, then claim the OpenID.
* a new user logs in with a yet-unknown OpenID, and needs to be registered.
This library will implement the protocol between the application and the OpenID provider, as well as produce redirects to be sent to the user's browser, and process incoming redirects from the provider.
The openid2rp module also includes a stand-alone server, as an example and a test.
The application can use the following API:
normalize_uri(uri) -> kind, url
Returns either 'xri' or 'uri' as kind; XRIs are not further supported. Applications should always normalize URIs claimed by the end user, and perform identity comparisons on the normalized URIs only.
discover(url) -> (services, op_endpoint, op_local)
Perform OpenID discovery on the URL. Return the list of services discovered (which should include either the signon or the server, in either version 1.0 or 2.0), the provider endpoint to be used for communication, and the provider-local identifier that the provider will validate. Applications need to remember the claimed identifier, and only identify the user by that string; the op_identifier is then not further relevant to the application.
associate(services, url) -> dict
Setup an association between the service and the provider. services must be the list of services that was returned from discovery; url is the provider endpoint URL. The resulting dictionary must be preserved atleast until authentication is completed, and can be reused at most until the 'expires_in' amount of seconds has passed.
request_authentication(services, url, assoc_handle, return_to,
claimed=None, op_local=None, realm=None) -> url
Create an authentication request; return the URL that the user should be redirected to. services and url are the same parameters as in associate; assoc_handle is the 'assoc_handle' field of the association and return_to is the URL on which the application will receive incoming provider redirects. If the user had claimed an identifier, this one and op_local from the discovery should be passed. Passing the realm allows the RP to receive the same identification information for multiple return_to URLs; for this to work, the return_to URL must match the realm (see 9.2. of the OpenID spec how matching is defined).
authenticate(session, response) -> None
Process an authentication response. session must be the established session (minimally including assoc_handle and mac_key), response is the query string as parsed by cgi.parse_qs. If authentication succeeds, return the list of signed fields. If the user was not authenticated, NotAuthenticated is raised. If the HTTP request is invalid (missing parameters, failure to validate signature), different exceptions will be raised, typically ValueError.
Callers must check openid.response_nonce for replay attacks.
What's New in This Release: [ read full changelog ]
· Implement direct verification (Jack Bates)
· Wrap verification in verify function; deprecate authenticate()
· Introduce symbolic error codes