Ignore:
Timestamp:
29/01/10 14:07:36 (11 years ago)
Author:
pjkersha
Message:
  • #1088 Important fix to AuthnRedirectResponseMiddleware? to set redirect ONLY when SSL client authentication has just succeeded in the upstream middleware AuthKitSSLAuthnMiddleware. This bug was causing the browser to redirect to the wrong place following OpenID sign in in the case where the user is already logged into their provider and selects a new relying party to sign into.
    • Improvements to Provider decide page interface: leave out messages about attributes that the provider can't retrieve for the RP. Also included NDG style help icon.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/provider/__init__.py

    r6354 r6440  
    8585# Place here to avoid circular import error with IdentityMapping class      
    8686from ndg.security.server.wsgi.openid.provider.authninterface import ( 
    87     AbstractAuthNInterface, AuthNInterfaceError) 
     87    AbstractAuthNInterface, AuthNInterfaceError,  
     88    AuthNInterfaceInvalidCredentials) 
    8889from ndg.security.server.wsgi.openid.provider.axinterface import (AXInterface, 
    8990    MissingRequiredAttrs, AXInterfaceReloginRequired) 
     
    127128    @type: defPaths: dict 
    128129     
    129     @cvar formRespWrapperTmpl: If the response to the Relying Party is too long 
    130     it's rendered as form with the POST method instead of query arguments in a  
    131     GET 302 redirect.  Wrap the form in this document to make the form submit  
    132     automatically without user intervention.  See _displayResponse method  
     130    @cvar FORM_RESP_WRAPPER_TMPL: If the response to the Relying Party is too  
     131    long it's rendered as form with the POST method instead of query arguments  
     132    in a GET 302 redirect.  Wrap the form in this document to make the form  
     133    submit automatically without user intervention.  See _displayResponse method  
    133134    below... 
    134     @type formRespWrapperTmpl: basestring""" 
    135      
    136     formRespWrapperTmpl = """<html> 
     135    @type FORM_RESP_WRAPPER_TMPL: basestring""" 
     136     
     137    FORM_RESP_WRAPPER_TMPL = """<html> 
    137138    <head> 
    138139        <script type="text/javascript"> 
    139140            function doRedirect() 
    140141            { 
     142                document.forms[0].style.visibility = "hidden"; 
    141143                document.forms[0].submit(); 
    142144            } 
     
    361363                            os.path.expandvars(opt['consumer_store_dirpath'])) 
    362364        self.oidserver = server.Server(store, self.urls['url_openidserver']) 
    363  
    364     def getCharset(self): 
    365         return self.__charset 
    366  
    367     def getPaths(self): 
    368         return self.__paths 
    369  
    370     def getBase_url(self): 
    371         return self.__base_url 
    372  
    373     def getUrls(self): 
    374         return self.__urls 
    375  
    376     def getMethod(self): 
    377         return self.__method 
    378  
    379     def getSessionMiddlewareEnvironKeyName(self): 
    380         return self.__sessionMiddlewareEnvironKeyName 
    381  
    382     def getSession(self): 
    383         return self.__session 
    384  
    385     def setCharset(self, value):         
    386         # Convert from string type where required    
    387         if not value: 
    388             self.__charset = '' 
    389         elif isinstance(value, basestring): 
    390             self.__charset = '; charset=' + value 
    391         else: 
    392             raise TypeError('Expecting string type for "charset" attribute; ' 
    393                             'got %r' % type(value)) 
    394  
    395     def setPaths(self, value): 
    396         if not isinstance(value, dict): 
    397             raise TypeError('Expecting dict type for ' 
    398                             '"paths" attribute; got %r' % 
    399                             type(value)) 
    400         self.__paths = value 
    401  
    402     def setBase_url(self, value): 
    403         if not isinstance(value, basestring): 
    404             raise TypeError('Expecting string type for ' 
    405                             '"base_url" attribute; got %r' % 
    406                             type(value)) 
    407         self.__base_url = value 
    408  
    409     def setUrls(self, value): 
    410         if not isinstance(value, dict): 
    411             raise TypeError('Expecting dict type for ' 
    412                             '"urls" attribute; got %r' % 
    413                             type(value)) 
    414         self.__urls = value 
    415  
    416     def setMethod(self, value): 
    417         if not isinstance(value, dict): 
    418             raise TypeError('Expecting dict type for ' 
    419                             '"method" attribute; got %r' % 
    420                             type(value)) 
    421         self.__method = value 
    422  
    423     def setSessionMiddlewareEnvironKeyName(self, value): 
    424         if not isinstance(value, basestring): 
    425             raise TypeError('Expecting string type for ' 
    426                             '"sessionMiddlewareEnvironKeyName" attribute; ' 
    427                             'got %r' % 
    428                             type(value)) 
    429         self.__sessionMiddlewareEnvironKeyName = value 
    430  
    431     def setSession(self, value): 
    432         if not isinstance(value, beaker.session.SessionObject): 
    433             raise TypeError('Expecting beaker.session.SessionObject type for ' 
    434                             '"session" attribute; got %r' % 
    435                             type(value)) 
    436  
    437         self.__session = value 
    438  
    439     def getOidResponse(self): 
    440         return self.__oidResponse 
    441  
    442     def getSregResponse(self): 
    443         return self.__sregResponse 
    444  
    445     def getAxResponse(self): 
    446         return self.__axResponse 
    447  
    448     def getOidserver(self): 
    449         return self.__oidserver 
    450  
    451     def getQuery(self): 
    452         return self.__query 
    453  
    454     def getTrustedRelyingParties(self): 
    455         return self.__trustedRelyingParties 
    456  
    457     def setOidResponse(self, value): 
    458         if not isinstance(value, server.OpenIDResponse): 
    459             raise TypeError('Expecting OpenIDResponse type for ' 
    460                             '"oidResponse" attribute; got %r' % 
    461                             type(value)) 
    462         self.__oidResponse = value 
    463  
    464     def setSregResponse(self, value): 
    465         self.__sregResponse = value 
    466  
    467     def setAxResponse(self, value): 
    468         if not isinstance(value, AXInterface): 
    469             raise TypeError('Expecting AXInterface type for ' 
    470                             '"axResponse" attribute; got %r' % 
    471                             type(value)) 
    472         self.__axResponse = value 
    473  
    474     def setOidserver(self, value): 
    475         if not isinstance(value, server.Server): 
    476             raise TypeError('Expecting openid.server.server.Server type for ' 
    477                             '"oidserver" attribute; got %r' % 
    478                             type(value)) 
    479         self.__oidserver = value 
    480  
    481     def setQuery(self, value): 
    482         if not isinstance(value, dict): 
    483             raise TypeError('Expecting dict type for ' 
    484                             '"query" attribute; got %r' % 
    485                             type(value)) 
    486         self.__query = value 
    487  
    488     def setTrustedRelyingParties(self, value): 
    489         if isinstance(value, basestring): 
    490             pat = OpenIDProviderMiddleware.TRUSTED_RELYINGPARTIES_SEP_PAT 
    491             self.__trustedRelyingParties = tuple([i for i in pat.split(value)]) 
    492              
    493         elif isinstance(value, (list, tuple)): 
    494             self.__trustedRelyingParties = tuple(value) 
    495         else: 
    496             raise TypeError('Expecting list or tuple type for ' 
    497                             '"trustedRelyingParties" attribute; got %r' % 
    498                             type(value)) 
    499365         
    500366    @classmethod 
     
    797663                identity = oidRequest.identity 
    798664 
    799             trust_root = oidRequest.trust_root 
    800             if self.query.get('remember', 'no').lower() == 'yes': 
    801                 self.session[ 
    802                     OpenIDProviderMiddleware.APPROVED_FLAG_SESSION_KEYNAME] = { 
    803                         trust_root: 'always' 
    804                     } 
    805                 self.session.save() 
    806              
     665            # Check for user selected to trust this RP for future logins. 
     666            self._applyTrustRoot(oidRequest) 
     667 
    807668            # Check for POST'ed user explicit setting of AX parameters 
    808669            self._applyUserAXSelections() 
     
    827688                                          code=400) 
    828689             
     690    def _applyTrustRoot(self, oidRequest): 
     691        """Check to see if user wants to trust the current Relying Party and if 
     692        so set record this decision in the session 
     693        """ 
     694        if self.query.get('remember', 'no').lower() == 'yes': 
     695            self.session[ 
     696                OpenIDProviderMiddleware.APPROVED_FLAG_SESSION_KEYNAME] = { 
     697                    oidRequest.trust_root: 'always' 
     698                } 
     699            self.session.save() 
     700                         
    829701    def _applyUserAXSelections(self): 
    830702        """Helper for do_allow method - process the query response checking  
     
    945817                                                environ, 
    946818                                                self.query['username']) 
     819                 
     820            except AuthNInterfaceInvalidCredentials: 
     821                log.error("No username %r matching an OpenID URL: %s", 
     822                          self.query.get('username'), 
     823                          traceback.format_exc()) 
     824                msg = ("No match was found for your account name.  Please " 
     825                       "check that your details are correct or contact the " 
     826                       "site administrator.") 
     827 
     828                response = self._render.login(environ, start_response, 
     829                                          msg=msg, 
     830                                          success_to=self.urls['url_decide']) 
     831                return response 
     832             
    947833            except Exception: 
    948                 log.error("Associating username %r with OpenID URL: %s"%  
    949                           (self.query.get('username'), 
    950                            traceback.format_exc())) 
    951                 msg = ("An internal error occured matching an OpenID " 
    952                        "to your account.  If the problem persists " 
    953                        "contact your system administrator.") 
    954  
    955                 response = self._render.errorPage(environ,  
    956                                                   start_response, 
    957                                                   msg)  
     834                log.error("Associating username %r with OpenID URL: %s",  
     835                          self.query.get('username'), 
     836                          traceback.format_exc()) 
     837                msg = ("An error occured matching an OpenID to your account. " 
     838                       "If the problem persists contact the site " 
     839                       "administrator.") 
     840 
     841                response = self._render.login(environ, start_response, 
     842                                          msg=msg, 
     843                                          success_to=self.urls['url_decide']) 
    958844                return response 
    959845 
     
    14481334            # Wrap in HTML with Javascript OnLoad to submit the form 
    14491335            # automatically without user intervention 
    1450             response = OpenIDProviderMiddleware.formRespWrapperTmpl % \ 
     1336            response = OpenIDProviderMiddleware.FORM_RESP_WRAPPER_TMPL % \ 
    14511337                                                        webresponse.body 
    14521338        else: 
     
    14781364                        ('Location', url)]) 
    14791365        return [] 
     1366 
     1367    def getCharset(self): 
     1368        return self.__charset 
     1369 
     1370    def getPaths(self): 
     1371        return self.__paths 
     1372 
     1373    def getBase_url(self): 
     1374        return self.__base_url 
     1375 
     1376    def getUrls(self): 
     1377        return self.__urls 
     1378 
     1379    def getMethod(self): 
     1380        return self.__method 
     1381 
     1382    def getSessionMiddlewareEnvironKeyName(self): 
     1383        return self.__sessionMiddlewareEnvironKeyName 
     1384 
     1385    def getSession(self): 
     1386        return self.__session 
     1387 
     1388    def setCharset(self, value):         
     1389        # Convert from string type where required    
     1390        if not value: 
     1391            self.__charset = '' 
     1392        elif isinstance(value, basestring): 
     1393            self.__charset = '; charset=' + value 
     1394        else: 
     1395            raise TypeError('Expecting string type for "charset" attribute; ' 
     1396                            'got %r' % type(value)) 
     1397 
     1398    def setPaths(self, value): 
     1399        if not isinstance(value, dict): 
     1400            raise TypeError('Expecting dict type for ' 
     1401                            '"paths" attribute; got %r' % 
     1402                            type(value)) 
     1403        self.__paths = value 
     1404 
     1405    def setBase_url(self, value): 
     1406        if not isinstance(value, basestring): 
     1407            raise TypeError('Expecting string type for ' 
     1408                            '"base_url" attribute; got %r' % 
     1409                            type(value)) 
     1410        self.__base_url = value 
     1411 
     1412    def setUrls(self, value): 
     1413        if not isinstance(value, dict): 
     1414            raise TypeError('Expecting dict type for ' 
     1415                            '"urls" attribute; got %r' % 
     1416                            type(value)) 
     1417        self.__urls = value 
     1418 
     1419    def setMethod(self, value): 
     1420        if not isinstance(value, dict): 
     1421            raise TypeError('Expecting dict type for ' 
     1422                            '"method" attribute; got %r' % 
     1423                            type(value)) 
     1424        self.__method = value 
     1425 
     1426    def setSessionMiddlewareEnvironKeyName(self, value): 
     1427        if not isinstance(value, basestring): 
     1428            raise TypeError('Expecting string type for ' 
     1429                            '"sessionMiddlewareEnvironKeyName" attribute; ' 
     1430                            'got %r' % 
     1431                            type(value)) 
     1432        self.__sessionMiddlewareEnvironKeyName = value 
     1433 
     1434    def setSession(self, value): 
     1435        if not isinstance(value, beaker.session.SessionObject): 
     1436            raise TypeError('Expecting beaker.session.SessionObject type for ' 
     1437                            '"session" attribute; got %r' % 
     1438                            type(value)) 
     1439 
     1440        self.__session = value 
     1441 
     1442    def getOidResponse(self): 
     1443        return self.__oidResponse 
     1444 
     1445    def getSregResponse(self): 
     1446        return self.__sregResponse 
     1447 
     1448    def getAxResponse(self): 
     1449        return self.__axResponse 
     1450 
     1451    def getOidserver(self): 
     1452        return self.__oidserver 
     1453 
     1454    def getQuery(self): 
     1455        return self.__query 
     1456 
     1457    def getTrustedRelyingParties(self): 
     1458        return self.__trustedRelyingParties 
     1459 
     1460    def setOidResponse(self, value): 
     1461        if not isinstance(value, server.OpenIDResponse): 
     1462            raise TypeError('Expecting OpenIDResponse type for ' 
     1463                            '"oidResponse" attribute; got %r' % 
     1464                            type(value)) 
     1465        self.__oidResponse = value 
     1466 
     1467    def setSregResponse(self, value): 
     1468        self.__sregResponse = value 
     1469 
     1470    def setAxResponse(self, value): 
     1471        if not isinstance(value, AXInterface): 
     1472            raise TypeError('Expecting AXInterface type for ' 
     1473                            '"axResponse" attribute; got %r' % 
     1474                            type(value)) 
     1475        self.__axResponse = value 
     1476 
     1477    def setOidserver(self, value): 
     1478        if not isinstance(value, server.Server): 
     1479            raise TypeError('Expecting openid.server.server.Server type for ' 
     1480                            '"oidserver" attribute; got %r' % 
     1481                            type(value)) 
     1482        self.__oidserver = value 
     1483 
     1484    def setQuery(self, value): 
     1485        if not isinstance(value, dict): 
     1486            raise TypeError('Expecting dict type for ' 
     1487                            '"query" attribute; got %r' % 
     1488                            type(value)) 
     1489        self.__query = value 
     1490 
     1491    def setTrustedRelyingParties(self, value): 
     1492        if isinstance(value, basestring): 
     1493            pat = OpenIDProviderMiddleware.TRUSTED_RELYINGPARTIES_SEP_PAT 
     1494            self.__trustedRelyingParties = tuple([i for i in pat.split(value)]) 
     1495             
     1496        elif isinstance(value, (list, tuple)): 
     1497            self.__trustedRelyingParties = tuple(value) 
     1498        else: 
     1499            raise TypeError('Expecting list or tuple type for ' 
     1500                            '"trustedRelyingParties" attribute; got %r' % 
     1501                            type(value)) 
    14801502 
    14811503    charset = property(getCharset, setCharset, None, "Charset's Docstring") 
Note: See TracChangeset for help on using the changeset viewer.