1
Background association requests
2
###############################
4
This document describes how to make signing in with OpenID faster for
5
users of your application by never making the users wait for an
6
association to be made, but using associations when they're
7
available. Most OpenID libraries and applications attempt to make
8
associations during the discovery phase of the OpenID authentication
9
request. Because association requests may have to do Diffie-Hellman
10
key exchange, which is time consuming. Even if Diffie-Hellman key
11
exchange is not used, the user still needs to wait for the association
14
Setting up your application to make associations in the background
15
==================================================================
17
When making associations background, there are two components that
18
need access to the OpenID association store: the consumer application
19
and the background association fetcher. The consumer needs to be set
20
up to record the server URL for any request for which an association
21
does not exist or is expired instead of making a new association. The
22
background fetcher looks at the server URL queue and makes
23
associations for any server URLs that need them. After the
24
associations are made, the consumer will use them until they expire
25
again. While associations are expired or missing, the consumer will
26
use stateless mode to complete authentications with the servers that
29
The OpenID server endpoint URL queue
30
-----------------------------------------------------------------
32
You will have to set up a conduit between the consumer and the
33
background association fetcher so that the background association
34
fetcher knows what servers need associations. The background
35
association fetcher will not fetch associations for servers that
36
already have them, so the queue does not have to be very smart. It
37
could be as simple as a file to which the server URLs are
38
appended. Either way, the queue needs to be write-able by the consumer
39
and readable by the background fetcher.
41
Configuring the consumer
42
-----------------------------------------------------------------
44
Create a subclass of ``GenericConsumer`` that overrides
45
``_negotiateAssociation`` so that it just records the server URL that
46
needs an association::
48
from openid.consumer.consumer import GenericConsumer, Consumer
50
class LazyAssociationConsumer(GenericConsumer):
51
needs_assoc_file = None
53
def _negotiateAssociation(self, endpoint):
54
# Do whatever you need to do here to send the server_url to
55
# the queue. This example just appends it to a file.
56
self.needs_assoc_file.write(endpoint.server_url + '\n')
57
self.needs_assoc_file.flush()
59
You could also store the whole endpoint object. When you instantiate
60
the consumer, pass this generic consumer class to the controlling
63
return Consumer(session, store, consumer_class=LazyAssociationConsumer)
65
The background association fetcher
66
-----------------------------------------------------------------
68
The background association fetcher is just a script that should be
69
added to ``cron`` or triggered periodically. If you are ambitious, you
70
could make the background fetcher listen for inserts into the queue.
72
The background fetcher needs to do something similar to the following::
74
def refresh(consumer, endpoint):
75
if consumer.store.getAssociation(endpoint.server_url):
76
logging.info("We don't need to associate with %r", endpoint.server_url)
79
logging.info("Associating with %r", endpoint.server_url)
81
assoc = consumer._negotiateAssociation(endpoint)
83
elapsed = time.time() - now
84
logging.info('(%0.2f seconds) Associated with %r', elapsed,
86
consumer.store.storeAssociation(endpoint.server_url, assoc)
88
logging.error('Failed to make an association with %r',
91
The code in this example logs the amount of time that the association
92
request took. This is time that the user would have been waiting. The
93
``consumer`` in this example is a standard consumer, not the
94
``LazyAssociationConsumer`` that was defined in the section
95
above. This is important, because the lazy consumer above will not
96
actually make any associations.