Changeset 7168 for TI12-security


Ignore:
Timestamp:
13/07/10 11:25:18 (9 years ago)
Author:
pjkersha
Message:

Incomplete - task 2: XACML-Security Integration

  • testing ndg.security.server.wsgi.authz.pep.SamlPepMiddleware? in ndg.security.test.unit.authz.test_authz
Location:
TI12-security/trunk/NDGSecurity/python
Files:
2 added
4 edited
1 moved

Legend:

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

    r7164 r7168  
    88from ndg.saml.saml2.binding.soap.client.authzdecisionquery import \ 
    99                                            AuthzDecisionQuerySslSOAPBinding 
    10  
    11 class SamlPepConfigError(Exception): 
     10from ndg.security.server.wsgi.session import SessionHandlerMiddleware 
     11 
     12 
     13class SamlPepMiddlewareConfigError(Exception): 
    1214    """Error with SAML PEP configuration settings""" 
    1315     
     
    1517class SamlPepMiddleware(object): 
    1618    '''Policy Enforcement Point for ESG with SAML based Interface 
     19     
     20    @requires: ndg.security.server.wsgi.session.SessionHandlerMiddleware  
     21    instance upstream in the WSGI stack. 
     22     
     23    @cvar AUTHZ_DECISION_QUERY_PARAMS_PREFIX: prefix for SAML authorisation 
     24    decision query options in config file 
     25    @type AUTHZ_DECISION_QUERY_PARAMS_PREFIX: string 
     26     
     27    @cvar PARAM_NAMES: list of config option names 
     28    @type PARAM_NAMES: tuple 
    1729     
    1830    @ivar __client: SAML authorisation decision query client  
     
    2032    ''' 
    2133    AUTHZ_DECISION_QUERY_PARAMS_PREFIX = 'authzDecisionQuery.' 
    22     AUTHZ_SERVICE_URI_PARAM_NAME = 'authzServiceURI' 
    23      
    24     __slots__ = ('_app', '__client', '__authzServiceURI') 
     34    SESSION_KEY_PARAM_NAME = 'sessionKey' 
     35     
     36    CREDENTIAL_WALLET_SESSION_KEYNAME = \ 
     37        SessionHandlerMiddleware.CREDENTIAL_WALLET_SESSION_KEYNAME 
     38    USERNAME_SESSION_KEYNAME = \ 
     39        SessionHandlerMiddleware.USERNAME_SESSION_KEYNAME 
     40     
     41    PARAM_NAMES = ( 
     42        'authzServiceURI', 
     43        'sessionKey' 
     44    ) 
     45    __slots__ = ( 
     46        '_app', '__client', '__session', 
     47    ) + tuple(["__%s" % i for i in PARAM_NAMES]) 
     48    del i 
    2549     
    2650    def __init__(self, app): 
     
    3155        self._app = app 
    3256        self.__client = AuthzDecisionQuerySslSOAPBinding() 
     57        self.__session = None 
    3358        self.__authzServiceURI = None 
    34          
     59        self.__sessionKey = None 
     60 
     61    def _getClient(self): 
     62        return self.__client 
     63 
     64    def _setClient(self, value): 
     65        if not isinstance(value, basestring): 
     66            raise TypeError('Expecting string type for "client" attribute; ' 
     67                            'got %r' % type(value)) 
     68        self.__client = value 
     69 
     70    client = property(_getClient, _setClient,  
     71                      doc="SAML authorisation decision query SOAP client") 
     72 
     73    def _getSession(self): 
     74        return self.__session 
     75 
     76    def _setSession(self, value): 
     77        self.__session = value 
     78 
     79    session = property(_getSession, _setSession,  
     80                       doc="Beaker Security Session instance") 
     81 
     82    def _getAuthzServiceURI(self): 
     83        return self.__authzServiceURI 
     84 
     85    def _setAuthzServiceURI(self, value): 
     86        if not isinstance(value, basestring): 
     87            raise TypeError('Expecting string type for "authzServiceURI" ' 
     88                            'attribute; got %r' % type(value)) 
     89        self.__authzServiceURI = value 
     90 
     91    authzServiceURI = property(_getAuthzServiceURI, _setAuthzServiceURI,  
     92                               doc="Authorisation Service URI") 
     93 
     94    def _getSessionKey(self): 
     95        return self.__sessionKey 
     96 
     97    def _setSessionKey(self, value): 
     98        if not isinstance(value, basestring): 
     99            raise TypeError('Expecting string type for "sessionKey" attribute; ' 
     100                            'got %r' % type(value)) 
     101        self.__sessionKey = value 
     102 
     103    sessionKey = property(_getSessionKey, _setSessionKey,  
     104                          doc="environ key name for Beaker session object") 
     105 
    35106    def initialise(self, prefix='', **kw): 
    36107        '''Initialise object from keyword settings 
    37108         
    38         @type global_conf: dict         
    39         @param global_conf: PasteDeploy global configuration dictionary 
    40109        @type prefix: basestring 
    41110        @param prefix: prefix for configuration items 
    42         @type app_conf: dict         
    43         @param app_conf: PasteDeploy application specific configuration  
     111        @type kw: dict         
     112        @param kw: configuration settings 
    44113        dictionary 
    45         @raise SamlPepConfigError: no "authzServiceURI" setting 
     114        @raise SamlPepMiddlewareConfigError: missing option setting(s) 
    46115        ''' 
     116        # Parse authorisation decision query options 
    47117        queryPrefix = prefix + self.__class__.AUTHZ_DECISION_QUERY_PARAMS_PREFIX 
    48         self.__client.parseKeywords(prefix=queryPrefix) 
    49         authzServiceUriParamName = prefix + \ 
    50                                     self.__class__.AUTHZ_SERVICE_URI_PARAM_NAME 
    51                                      
    52         self.__authzServiceURI = kw.get(authzServiceUriParamName) 
    53         if self.__authzServiceURI is None: 
    54             raise SamlPepConfigError('No %r setting for the authorisation ' 
    55                                      'service URI' % authzServiceUriParamName) 
    56          
     118        self.client.parseKeywords(prefix=queryPrefix, **kw) 
     119             
     120        # Parse other options 
     121        for name in SamlPepMiddleware.PARAM_NAMES: 
     122            paramName = prefix + name 
     123            value = kw.get(paramName) 
     124            if value is None: 
     125                raise SamlPepMiddlewareConfigError('Missing option %r' %  
     126                                                   paramName) 
     127            setattr(self, name, value) 
     128                     
    57129    @classmethod 
    58130    def filter_app_factory(cls, app, global_conf, prefix='', **app_conf): 
     
    85157        @return: response 
    86158        """ 
     159        # Get reference to session object - SessionHandler middleware must be in 
     160        # place upstream of this middleware in the WSGI stack 
     161        if self.sessionKey not in environ: 
     162            raise SamlPepMiddlewareConfigError('No beaker session key "%s" ' 
     163                                               'found in environ' %  
     164                                               self.sessionKey) 
     165        self.session = environ[self.sessionKey] 
     166         
    87167        request = Request(environ) 
    88168        self.__client.resourceURI = request.url 
    89         print dir(self.__client) 
    90         self.__client.subjectID = request.remote_user 
     169        self.__client.subjectID = request.remote_user or '' 
    91170         
    92171        self.__client.send(uri=self.__authzServiceURI) 
     172         
     173        return self._app(environ, start_response) 
    93174 
    94175    def _createAuthzDecisionQuery(self, 
  • TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/unit/__init__.py

    r7077 r7168  
    4949    configDirEnvVarName = 'NDGSEC_TEST_CONFIG_DIR' 
    5050     
     51    AUTHORISATION_SERVICE_PORTNUM = 9443 
     52    AUTHORISATION_SERVICE_URI = 'https://localhost:%s/authorisation-service' % \ 
     53                                AUTHORISATION_SERVICE_PORTNUM 
     54    AUTHORISATION_SERVICE_INI_FILEPATH = mkDataDirPath( 
     55            os.path.join('authorisationservice', 'authorisation-service.ini')) 
     56                          
    5157    SITEA_ATTRIBUTEAUTHORITY_PORTNUM = 5000 
    5258    SITEB_ATTRIBUTEAUTHORITY_PORTNUM = 5100 
     
    192198                              BaseTestCase.SITEB_ATTRIBUTEAUTHORITY_PORTNUM), 
    193199                        withSSL=withSSL) 
    194  
     200         
     201    def startAuthorisationService(self,  
     202                                  withSSL=True,  
     203                                  port=AUTHORISATION_SERVICE_PORTNUM): 
     204        self.addService( 
     205            cfgFilePath=self.__class__.AUTHORISATION_SERVICE_INI_FILEPATH,  
     206            port=port, 
     207            withSSL=withSSL) 
     208         
    195209    def __del__(self): 
    196210        """Stop any services started with the addService method""" 
  • TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/unit/wsgi/authz/saml-test.ini

    r7164 r7168  
    2121paste.filter_app_factory=ndg.security.server.wsgi.authz.pep:SamlPepMiddleware.filter_app_factory 
    2222prefix = pep. 
    23 policy.filePath = %(here)s/saml-policy.xml 
    24  
    25 pep.authzServiceURI = https://localhost:9443/AuthorisationService 
     23pep.sessionKey = beaker.session.ndg.security 
     24pep.authzServiceURI = https://localhost:9443/authorisation-service 
    2625 
    2726pep.pepResultHandler = ndg.security.test.unit.wsgi.authz.test_authz.RedirectFollowingAccessDenied 
     
    3231 
    3332# If omitted, DN of SSL Cert is used 
    34 pep.authzDecisionQuery.issuerName =  
     33pep.authzDecisionQuery.issuerName = /O=NDG/OU=BADC/CN=test 
     34pep.authzDecisionQuery.issuerFormat = urn:oasis:names:tc:SAML:1.1:nameid-format:x509SubjectName 
    3535pep.authzDecisionQuery.subjectIdFormat = urn:esg:openid 
    3636pep.authzDecisionQuery.clockSkewTolerance = 0. 
  • TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/unit/wsgi/authz/test_authz.py

    r7164 r7168  
    2929from ndg.security.server.wsgi.authz.result_handler.redirect import \ 
    3030    HTTPRedirectPEPResultHandlerMiddleware 
    31 from ndg.security.server.wsgi.authz import SamlPIPMiddlewareConfigError 
    32  
     31from ndg.security.server.wsgi.authz.pep import SamlPepMiddlewareConfigError 
     32 
     33 
     34from uuid import uuid4 
     35from datetime import datetime, timedelta 
     36 
     37from ndg.saml.saml2.core import (SAMLVersion, Subject, NameID, Issuer,  
     38                                 AuthzDecisionQuery, AuthzDecisionStatement,  
     39                                 Status, StatusCode, StatusMessage,  
     40                                 DecisionType, Action, Conditions, Assertion) 
     41from ndg.saml.xml.etree import (AuthzDecisionQueryElementTree,  
     42                                ResponseElementTree) 
     43 
     44class TestAuthorisationServiceMiddleware(object): 
     45    """Test Authorisation Service interface stub""" 
     46    QUERY_INTERFACE_KEYNAME_OPTNAME = 'queryInterfaceKeyName' 
     47    RESOURCE_URI = 'http://localhost/dap/data/' 
     48    ISSUER_DN = '/O=Test/OU=Authorisation/CN=Service Stub' 
     49     
     50    def __init__(self, app, global_conf, **app_conf): 
     51        self.queryInterfaceKeyName = app_conf[ 
     52            TestAuthorisationServiceMiddleware.QUERY_INTERFACE_KEYNAME_OPTNAME] 
     53        self._app = app 
     54     
     55    def __call__(self, environ, start_response): 
     56        environ[self.queryInterfaceKeyName] = self.authzDecisionQueryFactory() 
     57        return self._app(environ, start_response) 
     58     
     59    def authzDecisionQueryFactory(self): 
     60        """Makes the authorisation decision""" 
     61         
     62        def authzDecisionQuery(query, response): 
     63            """Authorisation Decision Query interface called by the next  
     64            middleware in the stack the SAML SOAP Query interface middleware  
     65            instance 
     66            (ndg.saml.saml2.binding.soap.server.wsgi.queryinterface.SOAPQueryInterfaceMiddleware) 
     67            """ 
     68            now = datetime.utcnow() 
     69            response.issueInstant = now 
     70             
     71            # Make up a request ID that this response is responding to 
     72            response.inResponseTo = query.id 
     73            response.id = str(uuid4()) 
     74            response.version = SAMLVersion(SAMLVersion.VERSION_20) 
     75             
     76            response.status = Status() 
     77            response.status.statusCode = StatusCode() 
     78            response.status.statusCode.value = StatusCode.SUCCESS_URI 
     79            response.status.statusMessage = StatusMessage()         
     80            response.status.statusMessage.value = \ 
     81                                                "Response created successfully" 
     82                
     83            assertion = Assertion() 
     84            assertion.version = SAMLVersion(SAMLVersion.VERSION_20) 
     85            assertion.id = str(uuid4()) 
     86            assertion.issueInstant = now 
     87             
     88            authzDecisionStatement = AuthzDecisionStatement() 
     89             
     90            # Make some simple logic to simulate a full access policy 
     91            if query.resource == self.__class__.RESOURCE_URI: 
     92                if query.actions[0].value == Action.HTTP_GET_ACTION: 
     93                    authzDecisionStatement.decision = DecisionType.PERMIT 
     94                else: 
     95                    authzDecisionStatement.decision = DecisionType.DENY 
     96            else: 
     97                authzDecisionStatement.decision = DecisionType.INDETERMINATE 
     98                 
     99            authzDecisionStatement.resource = query.resource 
     100                 
     101            authzDecisionStatement.actions.append(Action()) 
     102            authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI 
     103            authzDecisionStatement.actions[-1].value = Action.HTTP_GET_ACTION 
     104            assertion.authzDecisionStatements.append(authzDecisionStatement) 
     105             
     106            # Add a conditions statement for a validity of 8 hours 
     107            assertion.conditions = Conditions() 
     108            assertion.conditions.notBefore = now 
     109            assertion.conditions.notOnOrAfter = now + timedelta(seconds=60*60*8) 
     110                    
     111            assertion.subject = Subject()   
     112            assertion.subject.nameID = NameID() 
     113            assertion.subject.nameID.format = query.subject.nameID.format 
     114            assertion.subject.nameID.value = query.subject.nameID.value 
     115                 
     116            assertion.issuer = Issuer() 
     117            assertion.issuer.format = Issuer.X509_SUBJECT 
     118            assertion.issuer.value = \ 
     119                                    TestAuthorisationServiceMiddleware.ISSUER_DN 
     120     
     121            response.assertions.append(assertion) 
     122            return response 
     123         
     124        return authzDecisionQuery 
    33125 
    34126class RedirectFollowingAccessDenied(PEPResultHandlerMiddleware): 
     
    98190    INI_FILE = 'saml-test.ini' 
    99191    THIS_DIR = path.dirname(path.abspath(__file__)) 
     192    SESSION_KEYNAME = 'beaker.session.ndg.security' 
     193     
    100194    def __init__(self, *args, **kwargs):        
    101195        BaseTestCase.__init__(self, *args, **kwargs) 
     
    109203            port=SamlWSGIAuthZTestCase.SITEA_SSL_ATTRIBUTEAUTHORITY_PORTNUM) 
    110204         
     205        self.startAuthorisationService() 
    111206 
    112207    def test01CatchNoBeakerSessionFound(self): 
     
    114209        # PEPFilterConfigError is raised if no beaker.session is set in  
    115210        # environ 
    116         try: 
    117             response = self.app.get('/test_200') 
    118         except SamlPIPMiddlewareConfigError, e: 
    119             print("ok - expected: %s exception: %s" % (e.__class__, e)) 
     211        self.assertRaises(SamlPepMiddlewareConfigError, self.app.get,  
     212                          '/test_200') 
    120213        
    121214    def test02Ensure200WithNotLoggedInAndUnsecuredURI(self): 
     
    125218         
    126219        # Simulate a beaker.session in the environ 
    127         extra_environ={'beaker.session.ndg.security':BeakerSessionStub()} 
     220        extra_environ={self.__class__.SESSION_KEYNAME:BeakerSessionStub()} 
    128221        response = self.app.get('/test_200', 
    129222                                extra_environ=extra_environ) 
     
    136229         
    137230        extra_environ = { 
    138             'beaker.session.ndg.security': 
    139                 BeakerSessionStub(username=SamlWSGIAuthZTestCase.OPENID_URI) 
     231            self.__class__.SESSION_KEYNAME: 
     232                BeakerSessionStub(username=self.__class__.OPENID_URI), 
     233            'REMOTE_USER': self.__class__.OPENID_URI 
    140234        } 
    141235        response = self.app.get('/test_401',  
     
    150244         
    151245        extra_environ = { 
    152             'beaker.session.ndg.security': 
     246            self.__class__.SESSION_KEYNAME: 
    153247                BeakerSessionStub(username=SamlWSGIAuthZTestCase.OPENID_URI) 
    154248        } 
     
    164258        # AuthZ middleware checks for username key in session set by AuthN 
    165259        # handler 
    166         extra_environ={'beaker.session.ndg.security':BeakerSessionStub()}         
     260        extra_environ={self.__class__.SESSION_KEYNAME:BeakerSessionStub()}         
    167261        response = self.app.get('/test_accessDeniedToSecuredURI', 
    168262                                extra_environ=extra_environ, 
     
    174268        # access 
    175269        extra_environ = { 
    176             'beaker.session.ndg.security': 
     270            self.__class__.SESSION_KEYNAME: 
    177271                BeakerSessionStub(username=SamlWSGIAuthZTestCase.OPENID_URI) 
    178272        } 
     
    190284        # by the policy file 
    191285        extra_environ = { 
    192             'beaker.session.ndg.security': 
     286            self.__class__.SESSION_KEYNAME: 
    193287                BeakerSessionStub(username=SamlWSGIAuthZTestCase.OPENID_URI) 
    194288        } 
     
    205299        # access 
    206300        extra_environ = { 
    207             'beaker.session.ndg.security': 
     301            self.__class__.SESSION_KEYNAME: 
    208302                BeakerSessionStub(username=SamlWSGIAuthZTestCase.OPENID_URI) 
    209303        } 
     
    231325    THIS_DIR = os.path.dirname(os.path.abspath(__file__)) 
    232326    INI_FILEPATH = path.join(THIS_DIR, INI_FILE) 
     327    SESSION_KEYNAME = 'beaker.session.ndg.security' 
    233328     
    234329    def __init__(self, *arg, **kw): 
     
    253348        # access 
    254349        extra_environ = { 
    255             'beaker.session.ndg.security': 
     350            self.__class__.SESSION_KEYNAME: 
    256351                        BeakerSessionStub(username=self.__class__.OPENID_URI) 
    257352        } 
Note: See TracChangeset for help on using the changeset viewer.