Changeset 4538


Ignore:
Timestamp:
05/12/08 09:18:56 (11 years ago)
Author:
pjkersha
Message:

OpenID Provider Authentication interface:

  • tested in ID Select mode. username to identifier look up can now return multiple identifiers in case support is required for a user to have multiple IDs as in for e.g. Yahoo.
  • TODO: write an AuthN extension to enable Session Manager based authentication for OpenID Provider.
Location:
TI12-security/trunk/python
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid_provider.py

    r4537 r4538  
    237237         
    238238        @rtype: tuple 
    239         @return: identifiers to be used to make OpenID user identity URLs. This 
    240         implementation only returns one 
     239        @return: identifiers to be used to make OpenID user identity URLs.  
    241240         
    242241        @raise AuthNInterfaceRetrieveError: error with retrieval of information 
     
    244243        """ 
    245244        try: 
    246             return (self._username2Identifier[username],) 
     245            return self._username2Identifier[username] 
    247246        except KeyError: 
    248247            raise AuthNInterfaceRetrieveError('No entries for "%s" user' %  
     
    625624 
    626625    def do_allow(self, environ, start_response): 
    627         """Handle allow request - user allow credentials to be passed back to 
    628         the Relying Party? 
     626        """Handle allow request processing the result of do_decide: does user  
     627        allow credentials to be passed back to the Relying Party? 
     628         
     629        This method expects the follow fields to have been set in the posted 
     630        form created by the RedneringInterface.decidePage method called by  
     631        do_decide: 
     632         
     633        'Yes'/'No': for return authentication details back to the RP or  
     634        abort return to RP respectively 
     635        'remember': remember the decision corresponding to the above 'Yes' 
     636        /'No'. 
     637        This may be set to 'Yes' or 'No' 
     638        'identity': set to the user's identity URL.  This usually is not  
     639        required since it can be obtained from oidRequest.identity attribute 
     640        but in ID Select mode, the identity URL will have been selected or set 
     641        in the decide page interface. 
     642         
    629643         
    630644        @type environ: dict 
     
    640654        if oidRequest is None: 
    641655            log.error("Suspected do_allow called from stale request") 
    642             #return self.app(environ, start_response) 
    643             response = self._render.errorPage(environ, start_response, 
    644                                               "Invalid request", 
    645                                               code=400) 
     656            return self._render.errorPage(environ, start_response, 
     657                                          "Invalid request", 
     658                                          code=400) 
    646659         
    647660        if 'Yes' in self.query: 
    648661            if oidRequest.idSelect(): 
    649                 identity = self.urls['url_id']+'/'+self.session['username'] 
     662                identity = self.query.get('identity') 
     663                if identity is None: 
     664                    log.error("No identity field set from decide page for " 
     665                              "processing in ID Select mode") 
     666                    return self._render.errorPage(environ, start_response, 
     667                                                  "An internal error has " 
     668                                                  "occurred setting the " 
     669                                                  "OpenID user identity") 
    650670            else: 
    651671                identity = oidRequest.identity 
    652672 
    653673            trust_root = oidRequest.trust_root 
    654             if self.query.get('remember', 'no') == 'yes': 
     674            if self.query.get('remember', 'No') == 'Yes': 
    655675                self.session['approved'] = {trust_root: 'always'} 
    656676                self.session.save() 
     
    660680            except Exception, e: 
    661681                log.error("Setting response following ID Approval: %s" % e) 
    662                 response = self._render.errorPage(environ, start_response, 
    663                     'Error setting response.  Please report the error to your ' 
    664                     'site administrator.') 
    665                 return response 
    666                            
    667             response = self._displayResponse(oidResponse) 
     682                return self._render.errorPage(environ, start_response, 
     683                                              'Error setting response. ' 
     684                                              'Please report the error to ' 
     685                                              'your site administrator.') 
     686            else: 
     687                return self._displayResponse(oidResponse) 
    668688         
    669689        elif 'No' in self.query: 
    670             # TODO: Check 'no' response is OK - no causes AuthKit's Relying  
     690            # TODO: Check 'No' response is OK - No causes AuthKit's Relying  
    671691            # Party implementation to crash with 'openid.return_to' KeyError 
    672692            # in Authkit.authenticate.open_id.process 
    673693            oidResponse = oidRequest.answer(False) 
    674             #response = self._displayResponse(oidResponse) 
    675             response = self._render.mainPage(environ, start_response)             
     694            #return self._displayResponse(oidResponse) 
     695            return self._render.mainPage(environ, start_response)             
    676696        else: 
    677             response = self._render.errorPage(environ, start_response, 
    678                                               'Expecting Yes/No in allow ' 
    679                                               'post. %r' % self.query, 
    680                                               code=400) 
    681          
    682         return response 
     697            return self._render.errorPage(environ, start_response, 
     698                                          'Expecting Yes/No in allow ' 
     699                                          'post. %r' % self.query, 
     700                                          code=400) 
    683701 
    684702 
     
    725743                oidRequest = self.session.get('lastCheckIDRequest') 
    726744                if oidRequest is None: 
    727                     log.error("Getting OpenID request for login - no request " 
     745                    log.error("Getting OpenID request for login - No request " 
    728746                              "found in session") 
    729747                    return self._render.errorPage(environ, start_response, 
     
    844862        '''Check that a user is authorized i.e. does a session exist for their 
    845863        username and if so does it correspond to the identity URL provided. 
    846         This last check doesn't apply for ID Select mode where no ID was input 
     864        This last check doesn't apply for ID Select mode where No ID was input 
    847865        at the Relying Party. 
    848866         
     
    861879            return True 
    862880         
    863         identifier = self._authN.username2UserIdentifiers(username) 
    864         identityURL = self.urls['url_id']+'/'+identifier 
    865         if oidRequest.identity != identityURL: 
     881        identifiers = self._authN.username2UserIdentifiers(username) 
     882        idURLBase = self.urls['url_id']+'/' 
     883        identityURLs = [idURLBase+i for i in identifiers] 
     884        if oidRequest.identity not in identityURLs: 
    866885            log.debug("OpenIDProviderMiddleware._identityIsAuthorized - " 
    867886                      "user is already logged in with a different ID=%s" % \ 
     
    929948            requiredAttr = ax_req.getRequiredAttrs() 
    930949            if len(requiredAttr) > 0: 
    931                 msg = ("Relying party requires these attributes: %s; but no" 
     950                msg = ("Relying party requires these attributes: %s; but No" 
    932951                       "Attribute exchange handler 'axResponseHandler' has " 
    933952                       "been set" % requiredAttr) 
     
    12881307        This enables them to confirm the OpenID to be sent back to the  
    12891308        Relying Party 
     1309 
     1310        These fields should be posted by this page ready for  
     1311        OpenIdProviderMiddleware.do_allow to process: 
     1312         
     1313        'Yes'/'No': for return authentication details back to the RP or  
     1314        abort return to RP respectively 
     1315        'remember': remember the decision corresponding to the above 'Yes' 
     1316        /'No'. 
     1317        This may be set to 'Yes' or 'No' 
     1318        'identity': set to the user's identity URL.  This usually is not  
     1319        required since it can be obtained from oidRequest.identity attribute 
     1320        but in ID Select mode, the identity URL will have been selected or set 
     1321        here. 
     1322         
    12901323         
    12911324        @type environ: dict 
     
    14841517        @return: WSGI response 
    14851518        """ 
    1486         id_url_base = self.urls['url_id'] + '/' 
    1487          
    1488         # XXX: This may break if there are any synonyms for id_url_base, 
     1519        idURLBase = self.urls['url_id'] + '/' 
     1520         
     1521        # XXX: This may break if there are any synonyms for idURLBase, 
    14891522        # such as referring to it by IP address or a CNAME. 
    14901523         
     
    14951528        # which this is based.  - Check is the example code based on OpenID 1.0 
    14961529        # and therefore wrong for this behaviour? 
    1497 #        assert oidRequest.identity.startswith(id_url_base), \ 
    1498 #               repr((oidRequest.identity, id_url_base)) 
    1499         userIdentifier = oidRequest.identity[len(id_url_base):] 
     1530#        assert oidRequest.identity.startswith(idURLBase), \ 
     1531#               repr((oidRequest.identity, idURLBase)) 
     1532        userIdentifier = oidRequest.identity[len(idURLBase):] 
    15001533        username = environ['beaker.session']['username'] 
    15011534         
    15021535        if oidRequest.idSelect(): # We are being asked to select an ID 
    15031536            userIdentifier = self._authN.username2UserIdentifiers(username)[0] 
    1504             userOpenIDURL = id_url_base + userIdentifier 
     1537            identity = idURLBase + userIdentifier 
    15051538             
    15061539            msg = '''\ 
     
    15131546            ''' 
    15141547            fdata = { 
    1515                 'path_allow': self.urls['url_allow'], 
    1516                 'id_url_base': id_url_base, 
     1548                'pathAllow': self.urls['url_allow'], 
     1549                'identity': identity, 
    15171550                'trust_root': oidRequest.trust_root, 
    15181551                } 
    15191552            form = '''\ 
    1520 <form method="POST" action="%(path_allow)s"> 
     1553<form method="POST" action="%(pathAllow)s"> 
    15211554<table> 
    15221555  <tr><td>Identity:</td> 
    1523      <td>%(id_url_base)s<input type='text' name='identifier'></td></tr> 
     1556     <td>%(identity)s</td></tr> 
    15241557  <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr> 
    15251558</table> 
    15261559<p>Allow this authentication to proceed?</p> 
    1527 <input type="checkbox" id="remember" name="remember" value="yes" 
     1560<input type="checkbox" id="remember" name="remember" value="Yes" 
    15281561    /><label for="remember">Remember this 
    15291562    decision</label><br /> 
     1563<input type="hidden" name="identity" value="%(identity)s" /> 
    15301564<input type="submit" name="Yes" value="Yes" /> 
    15311565<input type="submit" name="No" value="No" /> 
     
    15331567''' % fdata 
    15341568             
    1535         elif userIdentifier == username: 
     1569        elif userIdentifier in self._authN.username2UserIdentifiers(username): 
    15361570            msg = '''\ 
    15371571            <p>A new site has asked to confirm your identity.  If you 
     
    15421576 
    15431577            fdata = { 
    1544                 'path_allow': self.urls['url_allow'], 
     1578                'pathAllow': self.urls['url_allow'], 
    15451579                'identity': oidRequest.identity, 
    15461580                'trust_root': oidRequest.trust_root, 
     
    15521586</table> 
    15531587<p>Allow this authentication to proceed?</p> 
    1554 <form method="POST" action="%(path_allow)s"> 
    1555   <input type="checkbox" id="remember" name="remember" value="yes" 
     1588<form method="POST" action="%(pathAllow)s"> 
     1589  <input type="checkbox" id="remember" name="remember" value="Yes" 
    15561590      /><label for="remember">Remember this 
    15571591      decision</label><br /> 
     
    15721606 
    15731607            fdata = { 
    1574                 'path_allow': self.urls['url_allow'], 
     1608                'pathAllow': self.urls['url_allow'], 
    15751609                'identity': oidRequest.identity, 
    15761610                'trust_root': oidRequest.trust_root, 
     
    15831617</table> 
    15841618<p>Allow this authentication to proceed?</p> 
    1585 <form method="POST" action="%(path_allow)s"> 
    1586   <input type="checkbox" id="remember" name="remember" value="yes" 
     1619<form method="POST" action="%(pathAllow)s"> 
     1620  <input type="checkbox" id="remember" name="remember" value="Yes" 
    15871621      /><label for="remember">Remember this 
    15881622      decision</label><br /> 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/combinedservices/serverapp.py

    r4521 r4538  
    11#!/usr/bin/env python 
    2 """NDG Security test harness for Ccombined Session Manager and Attribute 
     2"""NDG Security test harness for combined Session Manager and Attribute 
    33Authority services running under a single Paste instance. 
    44 
Note: See TracChangeset for help on using the changeset viewer.