Ignore:
Timestamp:
13/05/09 15:00:34 (10 years ago)
Author:
pjkersha
Message:

Further improvements to the authorization middleware:

  • PEPFilter no longer explicitly calls the PEPResultHandlerMiddleware (This latter class is the WSGI component which handles the access denied response that the server returns). This is not necessary as it can set a 403 response in order to trigger multiHandlerIntercept callback function set in the MultiHandler? instance. This responds to all 403 type status codes by invoking the PEPResultHandlerMiddleware.
  • ndg.security.common.authz.msi: improvements to the PDP, PIP and Response classes.
  • ndg.security.test.integration.dap: added integration test for secured pyDAP service
File:
1 edited

Legend:

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

    r5279 r5280  
    1111import logging 
    1212log = logging.getLogger(__name__) 
     13from time import time 
    1314import httplib 
    1415 
     
    5455        self.session = self.environ.get(self.sessionKey) 
    5556        if not self.isAuthenticated: 
    56             response = "Not authenticated" 
    57             start_response(self.__class__.getStatusMessage(401), 
    58                            [('Content-type', 'text/plain') , 
    59                             ('Content-length', str(len(response)))]) 
    60             return response 
     57            # This condition should be caught be the PEPFilter 
     58            log.warning("PEPResultHandlerMiddleware: user is not " 
     59                        "authenticated - setting HTTP 401 response") 
     60            return self._setErrorResponse(code=401) 
    6161        else: 
    6262            # TODO: refactor to include a call to another interface - possibly 
    6363            # - another WSGI to set a user friendly output and include links 
    6464            # to enable the user to register for new access privileges 
    65             response = ("Access is forbidden for this resource.\n\nPlease " 
    66                         "check with your site administrator that you have " 
    67                         "the required access privileges") 
    68             start_response(self.__class__.getStatusMessage(403), 
    69                            [('Content-type', 'text/plain') , 
    70                             ('Content-length', str(len(response)))]) 
    71             return response 
     65             
     66            # Get response message from PDP recorded by PEP 
     67            msg = getattr(self.session.get('pepCtx', {}).get('response'), 
     68                          'message', '') 
     69                 
     70            response = \ 
     71"""Access is forbidden for this resource: 
     72%s 
     73Please check with your site administrator that you have the required access privileges. 
     74""" % msg.join('\n'*2) 
     75 
     76            return self._setErrorResponse(code=401, msg=response) 
    7277 
    7378 
     
    137142        if not self.isAuthenticated: 
    138143            log.info("PEPFilter: user is not authenticated") 
    139             return self.authZResult(environ, start_response) 
     144             
     145            # Set a 401 response for an authentication handler to capture 
     146            return self._setErrorResponse(code=401) 
    140147         
    141148        # Make a request object to pass to the PDP 
     
    153160                                                        'sessionManagerURI') 
    154161        request.resource[Resource.URI_NS] = resourceURI 
    155              
    156         response = self.pdp.evaluate(request) 
    157         permit = response.status == Response.DECISION_PERMIT 
    158         if permit: 
    159             log.info("PEPFilter: PDP using policy [%s] denied access for " 
    160                      "uri path [%s]", self.policyFilePath, resourceURI) 
     162 
     163         
     164        # Call the PDP 
     165        response = self.pdp.evaluate(request)         
     166         
     167        # Record the result in the user's session to enable later  
     168        # interrogation by the AuthZResultHandlerMiddleware 
     169        session['pepCtx'] = {'request': request, 'response': response, 
     170                             'timestamp': time()} 
     171        session.save() 
     172         
     173        if response.status == Response.DECISION_PERMIT: 
     174            log.debug("PEPFilter: PDP granted access for URI path [%s] " 
     175                      "using policy [%s]", resourceURI, self.policyFilePath) 
    161176             
    162177            return self._app(environ, start_response) 
    163178        else: 
    164             log.debug("PEPFilter: PDP using policy [%s] granted access for " 
    165                       "uri path [%s]", self.policyFilePath, resourceURI) 
    166             return self.authZResult(environ, start_response) 
    167  
    168     def _setAuthZResult(self, val): 
    169         if not isinstance(val, PEPResultHandlerMiddleware): 
    170             raise TypeError("Expecting AuthZResultMiddleware type; got %r" % 
    171                             val) 
    172         self._authZResult = val 
    173          
    174     def _getAuthZResult(self): 
    175         return getattr(self, '_authZResult', None) 
    176      
    177     authZResult = property(fget=_getAuthZResult, 
    178                            fset=_setAuthZResult, 
    179                            doc="middleware object to handle access denied " 
    180                                "response from PDP") 
    181      
     179            log.info("PEPFilter: PDP returned a status of [%s] " 
     180                     "denying access for URI path [%s] using policy [%s]",  
     181                     response.decisionValue2String[response.status], 
     182                     resourceURI, 
     183                     self.policyFilePath)  
     184             
     185            # Trigger AuthZResultHandlerMiddleware by setting a response  
     186            # with HTTP status code equal to the triggerStatus class attribute 
     187            # value 
     188            return self._setErrorResponse(code=int(PEPFilter.triggerStatus)) 
     189 
    182190    def _getMatchingTargets(self): 
    183191        """This method may only be called following __call__ as __call__ 
     
    214222            @type headers: list 
    215223            @param headers: HTTP response header content""" 
     224             
    216225            if status.startswith(PEPFilter.triggerStatus): 
    217                 log.info("Policy Enforcement Point found [%s] status for URI " 
    218                          "path [%s]: invoking access denied response", 
     226                log.info("PEPFilter: found [%s] status for URI path [%s]: " 
     227                         "invoking access denied response", 
    219228                         PEPFilter.triggerStatus, 
    220229                         environ['PATH_INFO']) 
     
    222231            else: 
    223232                # No match - it's publicly accessible 
    224                 log.debug("Policy Enforcement Point: the return status [%s] " 
    225                           "for this URI path [%s] didn't match the trigger " 
    226                           "status [%s]", 
     233                log.debug("PEPFilter: the return status [%s] for this URI " 
     234                          "path [%s] didn't match the trigger status [%s]", 
    227235                          status, 
    228236                          environ['PATH_INFO'], 
     
    272280         
    273281        app.add_checker(PEPFilter.id, pepInterceptFunc)                 
    274         pepFilter.authZResult = app.binding[PEPFilter.id] 
    275282         
    276283        super(AuthorizationMiddleware, self).__init__(app, 
Note: See TracChangeset for help on using the changeset viewer.