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/session.py

    r6271 r6440  
    148148                      "path [%s]", self.signoutPath) 
    149149             
    150             referrer = environ.get('HTTP_REFERER') 
    151             if referrer is not None: 
    152                 def _start_response(status, header, exc_info=None): 
    153                     """Alter the header to send a redirect to the logout 
    154                     referrer address""" 
    155                     filteredHeader = [(field, val) for field, val in header  
    156                                       if field.lower() != 'location']         
    157                     filteredHeader.extend([('Location', referrer)]) 
    158                     return start_response(self.getStatusMessage(302),  
    159                                           filteredHeader, 
    160                                           exc_info) 
    161                      
    162             else: 
    163                 log.error('No referrer set for redirect following logout') 
    164                 _start_response = start_response 
    165                  
    166             # Clear user details from beaker session 
    167             for keyName in self.__class__.SESSION_KEYNAMES: 
    168                 session.pop(keyName, None) 
    169             session.save() 
     150            _start_response = self._doLogout(environ, start_response, session) 
    170151        else: 
    171152            log.debug("SessionHandlerMiddleware.__call__: checking for " 
    172153                      "REMOTE_* environment variable settings set by OpenID " 
    173154                      "Relying Party signin...") 
    174              
    175             if SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME not in session\ 
    176                and SessionHandlerMiddleware.USERNAME_ENVIRON_KEYNAME in environ: 
    177                 log.debug("SessionHandlerMiddleware.__call__: updating session " 
    178                           "username=%s", environ[ 
    179                             SessionHandlerMiddleware.USERNAME_ENVIRON_KEYNAME]) 
     155            self._setSession(environ, session) 
     156 
     157            _start_response = start_response 
     158             
     159        return self._app(environ, _start_response) 
     160     
     161    def _doLogout(self, environ, start_response, session): 
     162        """Execute logout action,  
     163         - clear the beaker session 
     164         - set the referrer URI to redirect back to by setting a custom  
     165        start_response function which modifies the HTTP header setting the 
     166        location field for a redirect 
     167         
     168        @param environ: environment dictionary 
     169        @type environ: dict like object 
     170        @type start_response: function 
     171        @param start_response: standard WSGI start response function 
     172        @param session: beaker session 
     173        @type session: beaker.session.SessionObject 
     174        """ 
     175             
     176        # Clear user details from beaker session 
     177        for keyName in self.__class__.SESSION_KEYNAMES: 
     178            session.pop(keyName, None) 
     179        session.save() 
     180         
     181        referrer = environ.get('HTTP_REFERER') 
     182        if referrer is not None: 
     183            def _start_response(status, header, exc_info=None): 
     184                """Alter the header to send a redirect to the logout 
     185                referrer address""" 
     186                filteredHeader = [(field, val) for field, val in header  
     187                                  if field.lower() != 'location']         
     188                filteredHeader.extend([('Location', referrer)]) 
     189                return start_response(self.getStatusMessage(302),  
     190                                      filteredHeader, 
     191                                      exc_info) 
    180192                 
    181                 session[SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME 
    182                         ] = environ[ 
    183                             SessionHandlerMiddleware.USERNAME_ENVIRON_KEYNAME] 
    184                 session.save() 
    185                  
    186             remoteUserData = environ.get( 
     193            return _start_response         
     194        else: 
     195            log.error('No referrer set for redirect following logout') 
     196            return start_response 
     197         
     198    def _setSession(self, environ, session): 
     199        """Check for REMOTE_USER and REMOTE_USER_DATA set by authentication 
     200        handlers and set a new session from them if present 
     201         
     202        @type environ: dict like object 
     203        @param environ: WSGI environment variables dictionary 
     204        @param session: beaker session 
     205        @type session: beaker.session.SessionObject 
     206        """ 
     207         
     208        # Set user id 
     209        if (SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME not in session 
     210            and SessionHandlerMiddleware.USERNAME_ENVIRON_KEYNAME in environ): 
     211             
     212            log.debug("SessionHandlerMiddleware.__call__: updating session " 
     213                      "username=%s", environ[ 
     214                        SessionHandlerMiddleware.USERNAME_ENVIRON_KEYNAME]) 
     215             
     216            session[SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME 
     217                    ] = environ[ 
     218                        SessionHandlerMiddleware.USERNAME_ENVIRON_KEYNAME] 
     219            session.save() 
     220             
     221        # Check for auxiliary user data 
     222        remoteUserData = environ.get( 
    187223                        SessionHandlerMiddleware.USERDATA_ENVIRON_KEYNAME, '')     
    188             if remoteUserData: 
    189                 log.debug("SessionHandlerMiddleware.__call__: found " 
    190                           "REMOTE_USER_DATA=%s, set from OpenID Relying Party " 
    191                           "signin",  
    192                           environ[ 
    193                               SessionHandlerMiddleware.USERDATA_ENVIRON_KEYNAME 
    194                           ]) 
     224        if remoteUserData: 
     225            log.debug("SessionHandlerMiddleware.__call__: found " 
     226                      "REMOTE_USER_DATA=%s, set from OpenID Relying Party " 
     227                      "signin",  
     228                      environ[ 
     229                          SessionHandlerMiddleware.USERDATA_ENVIRON_KEYNAME 
     230                      ]) 
     231             
     232            if (SessionHandlerMiddleware.SM_URI_SESSION_KEYNAME not in  
     233                session or  
     234                SessionHandlerMiddleware.ID_SESSION_KEYNAME not in session): 
    195235                 
    196236                # eval is safe here because AuthKit cookie is signed and  
    197                 # AuthKit middleware checks for tampering 
    198                 if (SessionHandlerMiddleware.SM_URI_SESSION_KEYNAME not in  
    199                     session or  
    200                     SessionHandlerMiddleware.ID_SESSION_KEYNAME not in session): 
    201                      
    202                     axData = eval(remoteUserData) 
    203                     if (isinstance(axData, dict) and  
    204                         SessionHandlerMiddleware.AX_KEYNAME in axData): 
     237                # AuthKit middleware checks for tampering             
     238                axData = eval(remoteUserData) 
     239                if (isinstance(axData, dict) and  
     240                    SessionHandlerMiddleware.AX_KEYNAME in axData): 
     241                     
     242                    ax = axData[SessionHandlerMiddleware.AX_KEYNAME] 
     243                     
     244                    # Save attributes keyed by attribute name 
     245                    session[SessionHandlerMiddleware.AX_SESSION_KEYNAME 
     246                            ] = SessionHandlerMiddleware._parseOpenIdAX(ax) 
     247                     
     248                    log.debug("SessionHandlerMiddleware.__call__: updated " 
     249                              "session with OpenID AX values: %r", 
     250                              session[ 
     251                                SessionHandlerMiddleware.AX_SESSION_KEYNAME 
     252                              ]) 
    205253                         
    206                         ax = axData[SessionHandlerMiddleware.AX_KEYNAME] 
     254                    # Save Session Manager specific attributes 
     255                    sessionManagerURI = ax.get( 
     256                            SessionHandlerMiddleware.SM_URI_AX_KEYNAME) 
    207257                         
    208                         # Save attributes keyed by attribute name 
    209                         session[ 
    210                             SessionHandlerMiddleware.AX_SESSION_KEYNAME 
    211                         ] = SessionHandlerMiddleware._parseOpenIdAX(ax) 
    212                          
    213                         log.debug("SessionHandlerMiddleware.__call__: updated " 
    214                                   "session with OpenID AX values: %r" %  
    215                                   session[ 
    216                                     SessionHandlerMiddleware.AX_SESSION_KEYNAME 
    217                                   ]) 
     258                    session[SessionHandlerMiddleware.SM_URI_SESSION_KEYNAME 
     259                            ] = sessionManagerURI 
     260 
     261                    sessionId = ax.get( 
     262                            SessionHandlerMiddleware.SESSION_ID_AX_KEYNAME) 
     263                    session[SessionHandlerMiddleware.ID_SESSION_KEYNAME 
     264                            ] = sessionId 
    218265                             
    219                         # Save Session Manager specific attributes 
    220                         sessionManagerURI = ax.get( 
    221                                 SessionHandlerMiddleware.SM_URI_AX_KEYNAME) 
    222                              
    223                         session[SessionHandlerMiddleware.SM_URI_SESSION_KEYNAME 
    224                                 ] = sessionManagerURI 
    225      
    226                         sessionId = ax.get( 
    227                                 SessionHandlerMiddleware.SESSION_ID_AX_KEYNAME) 
    228                         session[SessionHandlerMiddleware.ID_SESSION_KEYNAME 
    229                                 ] = sessionId 
    230                                  
    231                         session.save() 
    232                          
    233                         log.debug("SessionHandlerMiddleware.__call__: updated " 
    234                                   "session " 
    235                                   "with sessionManagerURI=%s and " 
    236                                   "sessionId=%s",  
    237                                   sessionManagerURI,  
    238                                   sessionId) 
    239                      
    240                 # Reset cookie removing user data 
    241                 setUser = environ[ 
     266                    session.save() 
     267                     
     268                    log.debug("SessionHandlerMiddleware.__call__: updated " 
     269                              "session " 
     270                              "with sessionManagerURI=%s and " 
     271                              "sessionId=%s",  
     272                              sessionManagerURI,  
     273                              sessionId) 
     274                 
     275            # Reset cookie removing user data by accessing the Auth ticket  
     276            # function available from environ 
     277            setUser = environ[ 
    242278                    SessionHandlerMiddleware.AUTH_TKT_SET_USER_ENVIRON_KEYNAME] 
    243                 setUser( 
    244                     session[SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME]) 
    245             else: 
    246                 log.debug("SessionHandlerMiddleware.__call__: REMOTE_USER_DATA " 
    247                           "is not set") 
    248  
    249             _start_response = start_response 
    250              
    251         return self._app(environ, _start_response) 
    252      
     279            setUser(session[SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME]) 
     280        else: 
     281            log.debug("SessionHandlerMiddleware.__call__: REMOTE_USER_DATA " 
     282                      "is not set") 
     283                     
    253284    @staticmethod                     
    254285    def _parseOpenIdAX(ax): 
Note: See TracChangeset for help on using the changeset viewer.