Changeset 7443


Ignore:
Timestamp:
03/09/10 14:42:43 (9 years ago)
Author:
pjkersha
Message:

Incomplete - task 2: XACML-Security Integration

  • Overhaul of test_context unit tests to make a more comprehensive test of policy rule evaluation.
Location:
TI12-security/trunk/ndg_xacml/ndg/xacml
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/ndg_xacml/ndg/xacml/core/context/result.py

    r7108 r7443  
    378378                                 '%r instead' % (Decision.TYPES, value)) 
    379379             
    380         return self.__value == value         
     380        return self.__value == value    
    381381 
    382382 
  • TI12-security/trunk/ndg_xacml/ndg/xacml/test/ndg1.xml

    r7351 r7443  
    1919                <!-- Pattern match all request URIs beginning with / --> 
    2020                <ResourceMatch MatchId="urn:oasis:names:tc:xacml:2.0:function:anyURI-regexp-match"> 
     21                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">^http://localhost/.*$</AttributeValue> 
    2122                    <ResourceAttributeDesignator 
    2223                        AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
    2324                        DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> 
    24                     <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">^http://localhost/.*$</AttributeValue> 
    2525                </ResourceMatch> 
    2626            </Resource> 
     
    2929     
    3030    <!-- Deny everything by default --> 
    31     <Rule RuleId="urn:ndg:security1.0:authz:test:DenyAllRule" Effect="Deny"/> 
     31    <Rule RuleId="DenyAllRule" Effect="Deny"/> 
    3232    <!--  
    3333        Following rules punch holes through the deny everything rule above 
     
    3535        Policy element above 
    3636    --> 
    37     <Rule RuleId="urn:ndgsecurity:secured-uri-rule" Effect="Permit"> 
     37    <Rule RuleId="ResourceBased" Effect="Permit"> 
    3838        <!--  
    39             Rule target(s) define which requests apply to the particular rule 
     39            Resource based restriction only 
     40        --> 
     41        <Target> 
     42            <Resources> 
     43                <Resource> 
     44                    <!-- Match the request URI --> 
     45                    <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> 
     46                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://localhost/resource-only-restricted</AttributeValue> 
     47                        <ResourceAttributeDesignator 
     48                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
     49                            DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> 
     50                    </ResourceMatch> 
     51                </Resource> 
     52            </Resources> 
     53        </Target> 
     54    </Rule> 
     55     
     56    <Rule RuleId="SingleSubjectRoleBased" Effect="Permit"> 
     57        <!--  
     58            Allow access based on a single subject role 
     59        --> 
     60        <Target> 
     61            <Subjects> 
     62                <Subject> 
     63                    <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> 
     64                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">staff</AttributeValue> 
     65                        <SubjectAttributeDesignator  
     66                            AttributeId="urn:ndg:security:authz:1.0:attr"  
     67                            DataType="http://www.w3.org/2001/XMLSchema#string"/> 
     68                    </SubjectMatch> 
     69                </Subject> 
     70            </Subjects> 
     71            <Resources> 
     72                <Resource> 
     73                    <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> 
     74                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://localhost/single-subject-role-restricted</AttributeValue> 
     75                        <ResourceAttributeDesignator 
     76                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
     77                            DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> 
     78                    </ResourceMatch> 
     79                </Resource> 
     80            </Resources> 
     81        </Target> 
     82    </Rule> 
     83 
     84    <Rule RuleId="SingleSubjectRoleBasedWithAction" Effect="Permit"> 
     85        <!--  
     86            Allow access based on a single subject role and given action 
     87        --> 
     88        <Target> 
     89            <Subjects> 
     90                <Subject> 
     91                    <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> 
     92                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">staff</AttributeValue> 
     93                        <SubjectAttributeDesignator  
     94                            AttributeId="urn:ndg:security:authz:1.0:attr"  
     95                            DataType="http://www.w3.org/2001/XMLSchema#string"/> 
     96                    </SubjectMatch> 
     97                </Subject> 
     98            </Subjects> 
     99            <Resources> 
     100                <Resource> 
     101                    <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> 
     102                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">http://localhost/action-and-single-subject-role-restricted</AttributeValue> 
     103                        <ResourceAttributeDesignator 
     104                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
     105                            DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> 
     106                    </ResourceMatch> 
     107                </Resource> 
     108            </Resources> 
     109            <Actions> 
     110                <Action> 
     111                    <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> 
     112                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> 
     113                        <ActionAttributeDesignator 
     114                            AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" 
     115                            DataType="http://www.w3.org/2001/XMLSchema#string"/> 
     116                    </ActionMatch> 
     117                </Action> 
     118            </Actions> 
     119        </Target> 
     120    </Rule> 
     121     
     122    <Rule RuleId="AtLeastOneSubjectAttributeBased" Effect="Permit"> 
     123        <!--  
     124            Subject must have at least one of a group of roles 
     125             
     126            Resource id is a regular expression 
    40127        --> 
    41128        <Target> 
     
    44131                    <!-- Pattern match the request URI --> 
    45132                    <ResourceMatch MatchId="urn:oasis:names:tc:xacml:2.0:function:anyURI-regexp-match"> 
     133                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">^http://localhost/at-least-of-subject-role-restricted.*$</AttributeValue> 
    46134                        <ResourceAttributeDesignator 
    47135                            AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
    48136                            DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> 
    49                         <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">^http://localhost/test_securedURI.*$</AttributeValue> 
    50137                    </ResourceMatch> 
    51138                </Resource> 
     
    78165                <Resource> 
    79166                    <ResourceMatch MatchId="urn:oasis:names:tc:xacml:2.0:function:anyURI-regexp-match"> 
    80                         <ResourceAttributeDesignator 
    81                             AttributeId="urn:siteA:security:authz:1.0:attr:resourceURI" 
    82                             DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> 
    83167                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">^http://localhost/test_accessDeniedToSecuredURI$</AttributeValue> 
     168                        <ResourceAttributeDesignator AttributeId="urn:ndg:security:authz:1.0:attr:resourceURI" DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> 
    84169                    </ResourceMatch> 
    85170                </Resource> 
  • TI12-security/trunk/ndg_xacml/ndg/xacml/test/test_context.py

    r7111 r7443  
    1818from ndg.xacml.test import XACML_NDGTEST1_FILEPATH 
    1919from ndg.xacml.parsers.etree.factory import ReaderFactory 
     20from ndg.xacml.core import Identifiers 
    2021from ndg.xacml.core.context.pdpinterface import PDPInterface 
    2122from ndg.xacml.core.context.pdp import PDP 
    2223from ndg.xacml.core.context.handler import CtxHandlerInterface 
    2324from ndg.xacml.core.attribute import Attribute 
    24 from ndg.xacml.core.attributevalue import AttributeValueClassFactory 
     25from ndg.xacml.core.attributevalue import (AttributeValue,  
     26                                           AttributeValueClassFactory) 
    2527from ndg.xacml.core.context.request import Request 
    2628from ndg.xacml.core.context.response import Response 
     
    3032from ndg.xacml.core.context.action import Action 
    3133 
    32                  
     34attributeValueFactory = AttributeValueClassFactory() 
     35AnyUriAttributeValue = attributeValueFactory(AttributeValue.ANY_TYPE_URI) 
     36StringAttributeValue = attributeValueFactory(AttributeValue.STRING_TYPE_URI) 
     37 
     38ROLE_ATTRIBUTE_ID = "urn:ndg:security:authz:1.0:attr" 
     39SUBJECT_ID = 'https://my.name.somewhere.ac.uk' 
     40 
    3341class TestContextHandler(CtxHandlerInterface): 
    34     """Test implementation of Context Handler""" 
     42    """Test implementation of Context Handler which includes an implemented PIP 
     43    interface""" 
    3544     
    3645    def __init__(self): 
     
    5261        # Convert myRequest to XACML context request - var assignment here is  
    5362        # representative of this process rather than actually doing anything. 
    54         request = myRequest 
     63        xacmlRequest = myRequest 
    5564         
    5665        if self.pdp is None: 
    5766            raise TypeError('No "pdp" attribute set') 
    5867         
    59         response = self.pdp.evaluate(request) 
     68        # Add a reference to this context so that the PDP can invoke queries 
     69        # back to the PIP 
     70        xacmlRequest.ctxHandler = self  
     71                
     72        xacmlResponse = self.pdp.evaluate(xacmlRequest) 
    6073         
    6174        # Convert XACML context response to domain specific request 
    62         myResponse = response 
     75        myResponse = xacmlResponse 
    6376         
    6477        return myResponse 
    65  
    66  
    67 class XACMLContextTestCase(unittest.TestCase): 
    68     """Test PDP, PAP, PIP and Context handler""" 
    69      
    70     def _createRequestCtx(self): 
     78     
     79    def pipQuery(self, request, designator): 
     80        '''PIP adds admin attribute value for given attribute ID and for any  
     81        subject''' 
     82        if designator.attributeId == ROLE_ATTRIBUTE_ID: 
     83            attrVal = StringAttributeValue(value='admin') 
     84            return [attrVal] 
     85        else: 
     86            return None 
     87 
     88 
     89class XacmlContextBaseTestCase(unittest.TestCase): 
     90    """Base class containing common methods for test initialisation""" 
     91     
     92    def _createRequestCtx(self,  
     93                          resourceId,  
     94                          includeSubject=True, 
     95                          subjectRoles=('staff',), 
     96                          roleAttributeId=ROLE_ATTRIBUTE_ID, 
     97                          action='read'): 
     98        """Create an example XACML Request Context for tests""" 
    7199        request = Request() 
    72         subject = Subject() 
    73          
    74         attributeValueFactory = AttributeValueClassFactory() 
    75          
    76         openidSubjectAttribute = Attribute() 
    77         roleAttribute = Attribute() 
    78          
    79         openidSubjectAttribute.attributeId = "urn:esg:openid" 
    80         AnyUriAttributeValue = attributeValueFactory( 
    81                                     'http://www.w3.org/2001/XMLSchema#anyURI') 
    82         openidSubjectAttribute.dataType = AnyUriAttributeValue.IDENTIFIER 
    83          
    84         openidSubjectAttribute.attributeValues.append(AnyUriAttributeValue()) 
    85         openidSubjectAttribute.attributeValues[-1].value = \ 
    86                                     'https://my.name.somewhere.ac.uk' 
    87          
    88         subject.attributes.append(openidSubjectAttribute) 
    89  
    90         StringAttributeValue = attributeValueFactory( 
    91                                     'http://www.w3.org/2001/XMLSchema#string') 
    92  
    93         roleAttribute.attributeId = "urn:ndg:security:authz:1.0:attr" 
    94         roleAttribute.dataType = StringAttributeValue.IDENTIFIER 
    95          
    96         roleAttribute.attributeValues.append(StringAttributeValue()) 
    97         roleAttribute.attributeValues[-1].value = 'staff'  
    98          
    99         subject.attributes.append(roleAttribute) 
    100                                    
    101         request.subjects.append(subject) 
     100         
     101        if includeSubject: 
     102            subject = Subject() 
     103            openidSubjectAttribute = Attribute() 
     104             
     105             
     106            openidSubjectAttribute.attributeId = "urn:esg:openid" 
     107            openidSubjectAttribute.dataType = AnyUriAttributeValue.IDENTIFIER 
     108             
     109            openidSubjectAttribute.attributeValues.append( 
     110                                                        AnyUriAttributeValue()) 
     111            openidSubjectAttribute.attributeValues[-1].value = SUBJECT_ID 
     112                                         
     113             
     114            subject.attributes.append(openidSubjectAttribute) 
     115     
     116            for role in subjectRoles: 
     117                roleAttribute = Attribute() 
     118                 
     119                roleAttribute.attributeId = roleAttributeId 
     120                roleAttribute.dataType = StringAttributeValue.IDENTIFIER 
     121                 
     122                roleAttribute.attributeValues.append(StringAttributeValue()) 
     123                roleAttribute.attributeValues[-1].value = role  
     124             
     125                subject.attributes.append(roleAttribute) 
     126                                       
     127            request.subjects.append(subject) 
    102128         
    103129        resource = Resource() 
     
    105131        resource.attributes.append(resourceAttribute) 
    106132         
    107         resourceAttribute.attributeId = \ 
    108                             "urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
     133        resourceAttribute.attributeId = Identifiers.Resource.RESOURCE_ID 
    109134                             
    110135        resourceAttribute.dataType = AnyUriAttributeValue.IDENTIFIER 
    111136        resourceAttribute.attributeValues.append(AnyUriAttributeValue()) 
    112         resourceAttribute.attributeValues[-1].value = \ 
    113                                             'http://localhost/test_securedURI' 
     137        resourceAttribute.attributeValues[-1].value = resourceId 
    114138 
    115139        request.resources.append(resource) 
     
    119143        request.action.attributes.append(actionAttribute) 
    120144         
    121         actionAttribute.attributeId = \ 
    122                                 "urn:oasis:names:tc:xacml:1.0:action:action-id" 
     145        actionAttribute.attributeId = Identifiers.Action.ACTION_ID 
    123146        actionAttribute.dataType = StringAttributeValue.IDENTIFIER 
    124147        actionAttribute.attributeValues.append(StringAttributeValue()) 
    125         actionAttribute.attributeValues[-1].value = 'read' 
     148        actionAttribute.attributeValues[-1].value = action 
    126149         
    127150        return request 
     151         
     152    def _createPDPfromPolicy(self): 
     153        pdp = PDP.fromPolicySource(XACML_NDGTEST1_FILEPATH, ReaderFactory) 
     154        return pdp     
     155 
     156 
     157class XacmlContextTestCase(XacmlContextBaseTestCase): 
     158    """Test PDP, PAP, PIP and Context handler""" 
    128159     
    129160    def test01CreateRequest(self): 
    130         requestCtx = self._createRequestCtx() 
     161        requestCtx = self._createRequestCtx("http://localhost") 
    131162        self.assert_(requestCtx) 
    132163         
     
    152183        self.assert_(pdp) 
    153184         
    154     def _createPDPfromPolicy(self): 
    155         pdp = PDP.fromPolicySource(XACML_NDGTEST1_FILEPATH, ReaderFactory) 
    156         return pdp 
    157          
    158185    def test07CreatePDPfromPolicy(self): 
    159186        pdp = self._createPDPfromPolicy() 
    160187        self.assert_(pdp) 
    161          
    162     def test08EvaluatePDP(self): 
    163         request = self._createRequestCtx() 
    164         pdp = self._createPDPfromPolicy() 
    165         response = pdp.evaluate(request) 
    166         self.assert_(response) 
    167  
    168          
     188     
     189     
     190class XacmlEvalPdpWithPermitOverridesPolicy(XacmlContextBaseTestCase): 
     191    """Test PDP with permit overrides rule combining algorithm""" 
     192     
     193    NOT_APPLICABLE_RESOURCE_ID = 'https://localhost' 
     194     
     195    # This could be any applicable resource value, provided there's no rule to 
     196    # override and enable access 
     197    PRIVATE_RESOURCE_ID = 'http://localhost/private-resource' 
     198     
     199    PUBLIC_RESOURCE_ID = 'http://localhost/resource-only-restricted' 
     200    NOT_APPLICABLE_RESOURCE_ID = 'https://localhost' 
     201         
     202    SINGLE_SUBJECT_ROLE_RESTRICTED_ID = \ 
     203        'http://localhost/single-subject-role-restricted' 
     204    ACTION_AND_SINGLE_SUBJECT_ROLE_RESTRICTED_ID = \ 
     205        'http://localhost/action-and-single-subject-role-restricted' 
     206    AT_LEAST_ONE_SUBJECT_ROLE_RESTRICTED_ID = \ 
     207        'http://localhost/at-least-of-subject-role-restricted' 
     208         
     209    def setUp(self): 
     210        self.pdp = self._createPDPfromPolicy() 
     211         
     212    def test01NotApplicable(self): 
     213        # Set a resource Id that doesn't match the main target 
     214        request = self._createRequestCtx( 
     215                                    self.__class__.NOT_APPLICABLE_RESOURCE_ID) 
     216        response = self.pdp.evaluate(request) 
     217        self.failIf(response is None, "Null response") 
     218        for result in response.results: 
     219            self.failIf(result.decision != Decision.NOT_APPLICABLE,  
     220                        "Expecting not applicable decision") 
     221         
     222    def test02PublicallyAccessibleResource(self): 
     223        # Test a resource which has no subject restrictions 
     224        request = self._createRequestCtx(self.__class__.PUBLIC_RESOURCE_ID, 
     225                                         includeSubject=False) 
     226        response = self.pdp.evaluate(request) 
     227        self.failIf(response is None, "Null response") 
     228        for result in response.results: 
     229            self.failIf(result.decision != Decision.PERMIT,  
     230                        "Expecting Permit decision") 
     231         
     232    def test03PrivateResource(self): 
     233        request = self._createRequestCtx( 
     234                                    self.__class__.PRIVATE_RESOURCE_ID) 
     235        response = self.pdp.evaluate(request) 
     236        self.failIf(response is None, "Null response") 
     237        for result in response.results: 
     238            self.failIf(result.decision != Decision.DENY,  
     239                        "Expecting Deny decision") 
     240 
     241    def test04SingleSubjectRoleRestrictedResource(self): 
     242        # Access based on a resource ID and single subject role 
     243        request = self._createRequestCtx( 
     244                            self.__class__.SINGLE_SUBJECT_ROLE_RESTRICTED_ID) 
     245        response = self.pdp.evaluate(request) 
     246        self.failIf(response is None, "Null response") 
     247        for result in response.results: 
     248            self.failIf(result.decision != Decision.PERMIT,  
     249                        "Expecting Permit decision")   
     250 
     251    def test05SingleSubjectRoleRestrictedResourceDeniesAccess(self): 
     252        # Subject doesn't have the required role for access 
     253        request = self._createRequestCtx( 
     254                            self.__class__.SINGLE_SUBJECT_ROLE_RESTRICTED_ID, 
     255                            subjectRoles=('student',)) 
     256        response = self.pdp.evaluate(request) 
     257        self.failIf(response is None, "Null response") 
     258        for result in response.results: 
     259            self.failIf(result.decision != Decision.DENY,  
     260                        "Expecting Deny decision")   
     261 
     262    def test06ActionAndSingleSubjectRoleRestrictedResource(self): 
     263        # Test restriction based on action type as well as subject role 
     264        request = self._createRequestCtx( 
     265                    self.__class__.ACTION_AND_SINGLE_SUBJECT_ROLE_RESTRICTED_ID) 
     266        response = self.pdp.evaluate(request) 
     267        self.failIf(response is None, "Null response") 
     268        for result in response.results: 
     269            self.failIf(result.decision != Decision.PERMIT,  
     270                        "Expecting Permit decision") 
     271 
     272    def test07ActionAndSingleSubjectRoleRestrictedResourceDeniesAccess(self): 
     273        # Test subject requests invalid action type 
     274        request = self._createRequestCtx( 
     275                    self.__class__.ACTION_AND_SINGLE_SUBJECT_ROLE_RESTRICTED_ID, 
     276                    action='write') 
     277        response = self.pdp.evaluate(request) 
     278        self.failIf(response is None, "Null response") 
     279        for result in response.results: 
     280            self.failIf(result.decision != Decision.DENY,  
     281                        "Expecting Deny decision")   
     282 
     283    def test08AtLeastOneSubjectRoleResource(self): 
     284        # Test at least one member function 
     285        request = self._createRequestCtx( 
     286                    self.__class__.AT_LEAST_ONE_SUBJECT_ROLE_RESTRICTED_ID, 
     287                    action='write') 
     288        response = self.pdp.evaluate(request) 
     289        self.failIf(response is None, "Null response") 
     290        for result in response.results: 
     291            self.failIf(result.decision != Decision.PERMIT,  
     292                        "Expecting Permit decision")              
     293 
     294    def test09AtLeastOneSubjectRoleResourceDeniesAccess(self): 
     295        # Test at least one member function where subject doesn't have one of 
     296        # the required roles 
     297        request = self._createRequestCtx( 
     298                    self.__class__.AT_LEAST_ONE_SUBJECT_ROLE_RESTRICTED_ID, 
     299                    subjectRoles=('student',)) 
     300        response = self.pdp.evaluate(request) 
     301        self.failIf(response is None, "Null response") 
     302        for result in response.results: 
     303            self.failIf(result.decision != Decision.DENY,  
     304                        "Expecting Deny decision")              
     305     
     306    def test10PipAddsRequiredAttributeValToEnableAccess(self): 
     307        # The PDP is part of a context handler with a PIP which adds subject 
     308        # attributes under prescribed conditions on the evaluation of  
     309        # subject attribute designators.  In this case the addition of the PIP 
     310        # adds an attribute value to one of the subject's attributes which means 
     311        # they're granted access where otherwise access would be denied 
     312        ctxHandler = TestContextHandler() 
     313        ctxHandler.pdp = self.pdp 
     314         
     315        request = self._createRequestCtx( 
     316                    self.__class__.AT_LEAST_ONE_SUBJECT_ROLE_RESTRICTED_ID, 
     317                    subjectRoles=('student',)) 
     318         
     319        response = ctxHandler.handlePEPRequest(request) 
     320        self.failIf(response is None, "Null response") 
     321        for result in response.results: 
     322            self.failIf(result.decision != Decision.PERMIT,  
     323                        "Expecting PERMIT decision")          
     324         
     325                                 
    169326if __name__ == "__main__": 
    170327    unittest.main() 
Note: See TracChangeset for help on using the changeset viewer.