Changeset 7143 for TI12-security/trunk


Ignore:
Timestamp:
01/07/10 08:53:38 (9 years ago)
Author:
pjkersha
Message:

Incomplete - task 2: XACML-Security Integration

  • working query interface middleware for authz decision interface unit tests
Location:
TI12-security/trunk/ndg_saml/ndg/saml
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/ndg_saml/ndg/saml/saml2/binding/soap/__init__.py

    r7130 r7143  
    1212__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1313__revision__ = "$Id$" 
     14class SOAPBindingError(Exception): 
     15    '''Base exception type for client SAML SOAP Binding''' 
     16 
     17 
     18class SOAPBindingInvalidResponse(SOAPBindingError): 
     19    '''Raise if the response is invalid''' 
     20    def __init__(self, *arg, **kw): 
     21        SOAPBindingInvalidResponse.__init__(self, *arg, **kw) 
     22        self.__response = None 
     23     
     24    def _getResponse(self): 
     25        '''Gets the response corresponding to this error 
     26         
     27        @return the response 
     28        ''' 
     29        return self.__response 
     30 
     31    def _setResponse(self, value): 
     32        '''Sets the response corresponding to this error. 
     33         
     34        @param value: the response 
     35        ''' 
     36        if not isinstance(value, Response): 
     37            raise TypeError('"response" must be a %r, got %r' % (Response, 
     38                                                                 type(value))) 
     39        self.__response = value 
     40         
     41    response = property(fget=_getResponse, fset=_setResponse,  
     42                        doc="SAML Response associated with this exception") 
  • TI12-security/trunk/ndg_saml/ndg/saml/saml2/binding/soap/client/__init__.py

    r7130 r7143  
    2424from ndg.soap.client import (UrlLib2SOAPClient, UrlLib2SOAPRequest) 
    2525 
    26  
    27 class SOAPBindingError(Exception): 
    28     '''Base exception type for client SAML SOAP Binding for Attribute Query''' 
    29  
    30  
    31 class SOAPBindingInvalidResponse(SOAPBindingError): 
    32     '''Raise if the response is invalid''' 
     26from ndg.saml.saml2.binding.soap import SOAPBindingInvalidResponse 
    3327     
    3428     
  • TI12-security/trunk/ndg_saml/ndg/saml/saml2/binding/soap/client/subjectquery.py

    r7130 r7143  
    2727class SubjectQueryResponseError(SOAPBindingInvalidResponse): 
    2828    """SAML Response error from Subject Query""" 
    29     def __init__(self, *arg, **kw): 
    30         SOAPBindingInvalidResponse.__init__(self, *arg, **kw) 
    31         self.__response = None 
    32      
    33     def _getResponse(self): 
    34         '''Gets the response corresponding to this error 
    35          
    36         @return the response 
    37         ''' 
    38         return self.__response 
    39  
    40     def _setResponse(self, value): 
    41         '''Sets the response corresponding to this error. 
    42          
    43         @param value: the response 
    44         ''' 
    45         if not isinstance(value, Response): 
    46             raise TypeError('"response" must be a %r, got %r' % (Response, 
    47                                                                  type(value))) 
    48         self.__response = value 
    49          
    50     response = property(fget=_getResponse, fset=_setResponse,  
    51                         doc="SAML Response associated with this exception") 
    5229     
    5330 
  • TI12-security/trunk/ndg_saml/ndg/saml/saml2/binding/soap/server/wsgi/queryinterface.py

    r7142 r7143  
    1919from ndg.soap.server.wsgi.middleware import SOAPMiddleware 
    2020from ndg.soap.etree import SOAPEnvelope 
    21 from ndg.soap.utils import str2Bool 
    22  
     21 
     22from ndg.saml.utils import str2Bool 
    2323from ndg.saml.utils.factory import importModuleObject 
    2424from ndg.saml.xml import UnknownAttrProfile 
     
    2727from ndg.saml.saml2.core import (Response, Status, StatusCode, StatusMessage,  
    2828                                 Issuer)  
     29from ndg.saml.saml2.binding.soap import SOAPBindingInvalidResponse 
    2930 
    3031 
     
    3738 
    3839 
     40class QueryIssueInstantInvalid(SOAPBindingInvalidResponse): 
     41    """Invalid timestamp for incoming query""" 
     42     
     43     
    3944class SOAPQueryInterfaceMiddleware(SOAPMiddleware): 
    4045    """Implementation of SAML 2.0 SOAP Binding for Query/Request Binding 
     
    8186        @param app: next middleware application in the chain  
    8287        '''      
    83         super(SOAPQueryInterfaceMiddleware, self).__init__(app, None) 
     88        super(SOAPQueryInterfaceMiddleware, self).__init__() 
    8489         
    8590        self._app = app 
     
    8994        self.__queryInterfaceKeyName = cls.DEFAULT_QUERY_INTERFACE_KEYNAME 
    9095        self.__mountPath = None 
    91         self.mountPath = ['/'] 
     96        self.mountPath = '/' 
    9297        self.__requestEnvelopeClass = None 
    9398        self.__responseEnvelopeClass = None 
     
    354359     
    355360        # Ignore non-matching path 
    356         if not self.pathMatch: 
     361        if environ['PATH_INFO'] not in (self.mountPath,  
     362                                        self.mountPath + '/'): 
    357363            return self._app(environ, start_response) 
    358364           
     
    394400            log.exception("%r raised parsing incoming query: %s" %  
    395401                          (type(e), traceback.format_exc())) 
    396             samlResponse.statusCode.value = StatusCode.UNKNOWN_ATTR_PROFILE_URI 
     402            samlResponse.status.statusCode.value = \ 
     403                                            StatusCode.UNKNOWN_ATTR_PROFILE_URI 
    397404        else:    
    398405            # Check for Query Interface in environ 
  • TI12-security/trunk/ndg_saml/ndg/saml/test/binding/soap/__init__.py

    r7142 r7143  
    1010__license__ = "http://www.apache.org/licenses/LICENSE-2.0" 
    1111__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    12 __revision__ = '$Id:$' 
     12__revision__ = '$Id$' 
    1313import os 
    1414import unittest 
     
    4242        self.app = paste.fixture.TestApp(wsgiapp) 
    4343          
    44         BaseTestCase.__init__(self, *args, **kwargs) 
     44        unittest.TestCase.__init__(self, *args, **kwargs) 
  • TI12-security/trunk/ndg_saml/ndg/saml/test/binding/soap/attribute-interface.ini

    r7140 r7143  
    1818 
    1919[app:TestApp] 
    20 paste.app_factory = ndg.security.test.unit.wsgi.saml:TestApp 
     20paste.app_factory = ndg.saml.test.binding.soap.test_soapattributeinterface:TestApp 
    2121 
    2222[filter:SAMLSoapAttributeInterfaceFilter] 
    23 paste.filter_app_factory = ndg.security.server.wsgi.saml:SOAPQueryInterfaceMiddleware.filter_app_factory 
     23paste.filter_app_factory = ndg.saml.saml2.binding.soap.server.wsgi.queryinterface:SOAPQueryInterfaceMiddleware.filter_app_factory 
    2424prefix = saml. 
    2525saml.pathMatchList = /attributeauthority/saml 
  • TI12-security/trunk/ndg_saml/ndg/saml/test/binding/soap/authz-decision-interface.ini

    r7142 r7143  
    11# 
    22# INI file for testing the SAML Authorisation Query interface.  It uses a 
    3 # test stub for the Authorisation Service rather than 
    4 # ndg.security.server.wsgi.authzservice.AuthzServiceMiddleware.  See, 
    5 # authz-service.ini to compare 
     3# test stub for the Authorisation Service  
    64# 
    75# The %(here)s variable will be replaced with the parent directory of this file 
  • TI12-security/trunk/ndg_saml/ndg/saml/test/binding/soap/authz-service.ini

    r7140 r7143  
    1818 
    1919[app:TestApp] 
    20 paste.app_factory = ndg.security.test.unit.wsgi.saml:TestApp 
     20paste.app_factory = ndg.saml.test.binding.soap:TestApp 
    2121 
    2222[filter:SAMLSoapAuthzDecisionInterfaceFilter] 
    23 paste.filter_app_factory = ndg.security.server.wsgi.saml:SOAPQueryInterfaceMiddleware.filter_app_factory 
     23paste.filter_app_factory = ndg.saml.saml2.binding.server.wsgi:SOAPQueryInterfaceMiddleware.filter_app_factory 
    2424prefix = saml. 
    2525saml.pathMatchList = /authorisationservice 
  • TI12-security/trunk/ndg_saml/ndg/saml/test/binding/soap/test_soapauthzdecisioninterface.py

    r7142 r7143  
    6464             
    6565            authzDecisionStatement = AuthzDecisionStatement() 
    66             authzDecisionStatement.decision = DecisionType.PERMIT 
    67             authzDecisionStatement.resource = \ 
    68                 TestAuthorisationServiceMiddleware.RESOURCE_URI 
     66             
     67            # Make some simple logic to simulate a full access policy 
     68            if query.resource == self.__class__.RESOURCE_URI: 
     69                if query.actions[0].value == Action.HTTP_GET_ACTION: 
     70                    authzDecisionStatement.decision = DecisionType.PERMIT 
     71                else: 
     72                    authzDecisionStatement.decision = DecisionType.DENY 
     73            else: 
     74                authzDecisionStatement.decision = DecisionType.INDETERMINATE 
     75                 
     76            authzDecisionStatement.resource = query.resource 
     77                 
    6978            authzDecisionStatement.actions.append(Action()) 
    7079            authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI 
     
    101110                            issuer="/O=Site A/CN=PEP", 
    102111                            subject="https://openid.localhost/philip.kershaw", 
    103                             resource=None, 
     112                            resource=RESOURCE_URI, 
    104113                            action=Action.HTTP_GET_ACTION, 
    105114                            actionNs=Action.GHPP_NS_URI): 
     
    117126        query.subject.nameID.format = "urn:ndg:saml:test:openid" 
    118127        query.subject.nameID.value = subject 
    119                                   
    120         if resource is None: 
    121             query.resource = self.__class__.RESOURCE_URI 
    122         else:    
    123             query.resource = resource 
     128    
     129        query.resource = resource 
    124130                  
    125131        query.actions.append(Action()) 
     
    162168        return response 
    163169     
    164     def test01ValidQuery(self): 
     170    def test01AccessGranted(self): 
    165171        query = self._createAuthzDecisionQuery() 
    166172        request = self._makeRequest(query=query) 
     
    187193        self.assert_(samlResponse.assertions[0].authzDecisionStatements[0 
    188194                                            ].decision == DecisionType.PERMIT) 
    189  
    190          
    191 class SOAPAuthzServiceMiddlewareTestCase( 
    192                                 SOAPAuthzDecisionInterfaceMiddlewareTestCase): 
    193     """Test the actual server side middleware  
    194     ndg.security.server.wsgi.authzservice.AuthzServiceMiddleware 
    195     rather than a test stub 
    196     """ 
    197     CONFIG_FILENAME = 'authz-service.ini' 
    198     RESOURCE_URI = 'http://localhost/dap/data/my.nc.dods?time[0:1:0]&lat' 
    199     ACCESS_DENIED_RESOURCE_URI = \ 
    200         'http://localhost/dap/data/test_accessDeniedToSecuredURI' 
    201      
    202     def __init__(self, *arg, **kw): 
    203         """Extend base init to include SAML Attribute Authority required by 
    204         Authorisation Service""" 
    205         super(SOAPAuthzDecisionInterfaceMiddlewareTestCase, self).__init__( 
    206                                                                     *arg, **kw) 
    207         self.startSiteAAttributeAuthority(withSSL=True, port=5443) 
    208          
     195    
    209196    def test02AccessDenied(self): 
    210         cls = SOAPAuthzServiceMiddlewareTestCase 
    211         query = self._createAuthzDecisionQuery( 
    212                                         resource=cls.ACCESS_DENIED_RESOURCE_URI) 
     197        query = self._createAuthzDecisionQuery(action=Action.HTTP_POST_ACTION) 
    213198        request = self._makeRequest(query=query) 
    214199         
     
    223208                                 status=200) 
    224209        print("Response status=%d" % response.status) 
     210         
    225211        samlResponse = self._getSAMLResponse(response.body) 
    226212 
     
    233219        self.assert_(samlResponse.assertions[0].authzDecisionStatements[0]) 
    234220        self.assert_(samlResponse.assertions[0].authzDecisionStatements[0 
    235                                             ].decision == DecisionType.DENY)    
    236      
    237      
     221                                            ].decision == DecisionType.DENY) 
     222         
     223    def test03IndeterminateResponse(self): 
     224        query = self._createAuthzDecisionQuery( 
     225                            resource=self.__class__.RESOURCE_URI + 'invalid') 
     226        request = self._makeRequest(query=query) 
     227         
     228        header = { 
     229            'soapAction': "http://www.oasis-open.org/committees/security", 
     230            'Content-length': str(len(request)), 
     231            'Content-type': 'text/xml' 
     232        } 
     233        response = self.app.post('/authorisationservice/',  
     234                                 params=request,  
     235                                 headers=header,  
     236                                 status=200) 
     237        print("Response status=%d" % response.status) 
     238         
     239        samlResponse = self._getSAMLResponse(response.body) 
     240 
     241        self.assert_(samlResponse.status.statusCode.value == \ 
     242                     StatusCode.SUCCESS_URI) 
     243        self.assert_(samlResponse.inResponseTo == query.id) 
     244        self.assert_(samlResponse.assertions[0].subject.nameID.value == \ 
     245                     query.subject.nameID.value) 
     246        self.assert_(samlResponse.assertions[0]) 
     247        self.assert_(samlResponse.assertions[0].authzDecisionStatements[0]) 
     248        self.assert_(samlResponse.assertions[0].authzDecisionStatements[0 
     249                                    ].decision == DecisionType.INDETERMINATE) 
     250         
     251 
    238252if __name__ == "__main__": 
    239253    unittest.main() 
  • TI12-security/trunk/ndg_saml/ndg/saml/utils/__init__.py

    r7130 r7143  
    3434                                                                format)[0:6])) 
    3535from datetime import datetime, timedelta 
     36 
    3637         
    37          
     38# Interpret a string as a boolean 
     39str2Bool = lambda str: str.lower() in ("yes", "true", "t", "1") 
     40 
     41       
    3842class SAMLDateTime(object): 
    3943    """Generic datetime formatting utility for SAML timestamps - XMLSchema 
Note: See TracChangeset for help on using the changeset viewer.