r77754 - tracker/instances/python-dev/extensions/openid_login.py
![](https://secure.gravatar.com/avatar/8ac615df352a970211b0e3d94a307c6d.jpg?s=120&d=mm&r=g)
Author: martin.v.loewis Date: Tue Jan 26 00:42:39 2010 New Revision: 77754 Log: Streamline authentication: recall claimed ID from session, discover provider-returned ID for consistency. Modified: tracker/instances/python-dev/extensions/openid_login.py Modified: tracker/instances/python-dev/extensions/openid_login.py ============================================================================== --- tracker/instances/python-dev/extensions/openid_login.py (original) +++ tracker/instances/python-dev/extensions/openid_login.py Tue Jan 26 00:42:39 2010 @@ -50,7 +50,34 @@ session.mac_key = session_data['mac_key'] session.expires = now + date.Interval(int(session_data['expires_in'])) self.db.commit() - return session + return session + + def authenticate(self, session, query): + '''Authenticate an OpenID indirect response, and return the claimed ID''' + try: + signed = openid.authenticate(session, query) + except Exception, e: + raise ValueError, "Authentication failed: "+str(e) + if openid.is_op_endpoint(session.stypes): + # Provider-guided login: provider ought to report claimed ID + if 'openid.claimed_id' in query: + claimed = query['openid.claimed_id'][0] + else: + raise ValueError, 'incomplete response' + # OpenID 11.2: verify that provider is authorized to assert ID + discovered = openid.discover(claimed) + if not discovered or discovered[1] != session.url: + raise ValueError, "Provider %s is not authorized to make assertions about %s" % (session.url, claimed) + else: + # User entered claimed ID, stored in session object + claimed = session.provider_id + if not openid.is_compat_1x(session.stypes): + # can only check correct claimed ID for OpenID 2.0 + if 'openid.claimed_id' not in query or claimed != query['openid.claimed_id'][0]: + # assertion is not about an ID, or about a different ID; refuse to accept + raise ValueError, "Provider did not assert your ID" + return claimed + class OpenidLogin(LoginAction, Openid): 'Extended versoin of LoginAction, supporting OpenID identifiers in username field.' @@ -107,7 +134,7 @@ session.assoc_handle, return_to, realm=realm) raise Redirect, url -class OpenidReturn(Action): +class OpenidReturn(Action, Openid): def handle(self): # parse again to get cgi kind of result query = cgi.parse_qs(self.client.env['QUERY_STRING']) @@ -152,20 +179,7 @@ except KeyError: raise ValueError, 'Not authenticated (no session)' session = self.db.openid_session.getnode(session[0]) - try: - signed = openid.authenticate(session, query) - except Exception, e: - import traceback - raise ValueError, "Authentication failed: "+traceback.format_exc() - if 'openid.claimed_id' in query: - if 'claimed_id' not in signed: - raise ValueError, 'Incomplete signature' - claimed = query['openid.claimed_id'][0] - else: - # OpenID 1, claimed ID not reported - should set cookie - if 'identity' not in signed: - raise ValueError, 'Incomplete signature' - claimed = query['openid.identity'][0] + claimed = self.authenticate(session, query) if self.user != 'anonymous': # Existing user claims OpenID @@ -244,7 +258,7 @@ self.db.user.set(self.userid, openids=' '.join(openids)) self.db.commit() -class OpenidRegister(RegisterAction): +class OpenidRegister(RegisterAction, Openid): def handle(self): query = {} if 'openid.identity' not in self.form: @@ -263,20 +277,7 @@ query[key].append(value) except KeyError: query[key] = [value] - try: - signed = openid.authenticate(session, query) - except Exception, e: - raise ValueError, "Authentication failed: "+repr(e) - if 'openid.claimed_id' in query: - if 'claimed_id' not in signed: - raise ValueError, 'Incomplete signature' - claimed = query['openid.claimed_id'][0] - else: - # OpenID 1, claimed ID not reported - should set cookie - if 'identity' not in signed: - raise ValueError, 'Incomplete signature' - claimed = query['openid.identity'][0] - + claimed = self.authenticate(session, query) # OpenID signature is still authentic, now pass it on to the base # register method; also fake password self.form.value.append(cgi.MiniFieldStorage('openids', claimed))
participants (1)
-
martin.v.loewis