def test02SendQuery(self):
        query_binding = AttributeQuerySslSOAPBinding()
        
        attribute_query = AttributeQueryFactory.create()
        attribute_query.subject.nameID.format = self.__class__.SUBJECT_FORMAT
        attribute_query.subject.nameID.value = self.__class__.SUBJECT
        attribute_query.issuerName = '/O=Site A/CN=Authorisation Service'


        attribute = Attribute()
        attribute.name = 'urn:ndg:saml:emailaddress'
        attribute.friendlyName = 'emailAddress'
        attribute.nameFormat = 'http://www.w3.org/2001/XMLSchema'
        
        attribute_query.attributes.append(attribute)
        
        query_binding.clockSkewTolerance = 2.
        query_binding.sslCACertDir = self.__class__.CLIENT_CACERT_DIR
        query_binding.sslCertFilePath = self.__class__.CLIENT_CERT_FILEPATH
        query_binding.sslPriKeyFilePath = self.__class__.CLIENT_PRIKEY_FILEPATH
        query_binding.sslValidDNs = self.__class__.VALID_DNS
        
        response = query_binding.send(attribute_query, 
                                      uri=self.__class__.SERVICE_URI)
        
        # Convert back to ElementTree instance read for string output
        samlResponseElem = ResponseElementTree.toXML(response)
        
        print("SAML Response ...")
        print(ElementTree.tostring(samlResponseElem))
        print("Pretty print SAML Response ...")
        print(prettyPrint(samlResponseElem))
        
        self.assert_(response.status.statusCode.value==StatusCode.SUCCESS_URI)
    def test01ValidQuery(self):        
        binding = AuthzDecisionQuerySslSOAPBinding()
        binding.actions.append(Action())
        binding.actions[0].namespace = EsgAuthzServiceTestCase.ACTION_NS_URI
        binding.actions[0].value = EsgAuthzServiceTestCase.ACTION    
        binding.resourceURI = EsgAuthzServiceTestCase.RESOURCE_URI
        binding.subjectID = EsgAuthzServiceTestCase.SUBJECT
        binding.issuerName = EsgAuthzServiceTestCase.ISSUER_NAME
        
        # SSL Context Proxy settings
        binding.sslCACertDir = EsgAuthzServiceTestCase.CA_DIR

        # Add tolerance of 1 second for clock skew either side of issue instant
        # and not before / notOnOrAfter times
        binding.clockSkewTolerance = 1
        
        response = binding.send(uri=EsgAuthzServiceTestCase.AUTHZ_SERVICE_URI)
        samlResponseElem = ResponseElementTree.toXML(response)
        
        print("SAML Response ...")
        print(ElementTree.tostring(samlResponseElem))
        print("Pretty print SAML Response ...")
        print(prettyPrint(samlResponseElem))


        self.assert_(response.status.statusCode.value == \
                     StatusCode.SUCCESS_URI)
        self.assert_(response.inResponseTo == binding.query.id)
        self.assert_(response.assertions[0])
        self.assert_(response.assertions[0].subject.nameID.value == \
                     binding.query.subject.nameID.value)
        self.assert_(response.assertions[0].authzDecisionStatements[0])
        self.assert_(response.assertions[0].authzDecisionStatements[0
                                            ].decision == DecisionType.PERMIT)
 def display_result(self, response):
     # Convert back to ElementTree instance read for string output
     saml_response_elem = ResponseElementTree.toXML(response)
     
     if self.pretty_print:
         print(prettyPrint(saml_response_elem))
     else:
         print(ElementTree.tostring(saml_response_elem))
Esempio n. 4
0
 def _serialize_authz_decision_query_response(self):
     response = SAMLUtil.create_authz_decision_query_response()
     
     # Create ElementTree Assertion Element
     responseElem = ResponseElementTree.toXML(response)
     self.assertTrue(ElementTree.iselement(responseElem))
     
     # Serialise to output        
     xmlOutput = prettyPrint(responseElem)
     return xmlOutput
Esempio n. 5
0
 def _serializeAuthzDecisionQueryResponse(self):
     response = self._createAuthzDecisionQueryResponse()
     
     # Create ElementTree Assertion Element
     responseElem = ResponseElementTree.toXML(response)
     self.assert_(ElementTree.iselement(responseElem))
     
     # Serialise to output        
     xmlOutput = prettyPrint(responseElem)
     return xmlOutput
Esempio n. 6
0
 def test05CreateAttributeQueryResponse(self):
     response = self._createAttributeQueryResponse()
     
     # Create ElementTree Assertion Element
     responseElem = ResponseElementTree.toXML(response)
     
     self.assert_(ElementTree.iselement(responseElem))
     
     # Serialise to output        
     xmlOutput = prettyPrint(responseElem)       
     self.assert_(len(xmlOutput))
     print("\n"+"_"*80)
     print(xmlOutput)
     print("_"*80)
Esempio n. 7
0
    def _getAttributes(self, subject):
        """Makes a query for the attributes and returns them.
        The attribute names used in the SAML query are mapped to keys to use in
        the session.
        @type subject: basestring
        @param subject: subject for which the query is to be made
        @rtype: dict of basestring
        @return: attribute names and values
        """
        attributeQuery = self._attributeQueryClient.makeQuery()
        if self.attributeServiceUrl:
            log.debug("Using configured attribute service URL; %s",
                      self.attributeServiceUrl)
            attributeServiceUrl = self.attributeServiceUrl
        else:
            attributeServiceUrl = self._getAttributeService(subject)

        self._attributeQueryClient.setQuerySubjectId(attributeQuery, subject)
        attributeQuery.attributes.extend(ESGFDefaultQueryAttributes.ATTRIBUTES)

        response = self._attributeQueryClient.send(attributeQuery,
                                                   uri=attributeServiceUrl)

        samlResponseElem = ResponseElementTree.toXML(response)

        if log.isEnabledFor(logging.DEBUG):
            log.debug("Pretty print SAML Response ...")
            log.debug(prettyPrint(samlResponseElem))
            # log.debug(ElementTree.tostring(samlResponseElem))

        returnValues = {}
        for assertion in response.assertions:
            for attrStmt in assertion.attributeStatements:
                for attr in attrStmt.attributes:
                    attrKey = self.__class__.ATTRIBUTE_NAME_MAP.get(attr.name)
                    if attrKey:
                        if len(attr.attributeValues) > 1:
                            value = []
                            for attrVal in attr.attributeValues:
                                value.append(attrVal.value)
                        else:
                            value = attr.attributeValues[0].value
                        returnValues[attrKey] = value
                        log.debug("Received attribute: %s = %s", attrKey,
                                  value)

        return returnValues
Esempio n. 8
0
    def __call__(self, environ, start_response):
        """Logs the request and response stored in the session.

        @type environ: dict
        @param environ: WSGI environment variables dictionary
        @type start_response: function
        @param start_response: standard WSGI start response function
        @rtype: iterable
        @return: response
        """
        session = environ.get('beaker.session.ndg.security')
        if session:
            pepCtx = session.get(SamlPepFilterBase.PEPCTX_SESSION_KEYNAME)
            if pepCtx:
                request = pepCtx.get(
                    SamlPepFilterBase.PEPCTX_REQUEST_SESSION_KEYNAME)
                if isinstance(request, AuthzDecisionQuery):
                    requestEtree = AuthzDecisionQueryElementTree.toXML(request)
                    log.debug("AuthzDecisionQuery:\n%s",
                              etree_utils.prettyPrint(requestEtree))
                elif isinstance(request, XACMLAuthzDecisionQuery):
                    requestEtree = XACMLAuthzDecisionQueryElementTree.toXML(
                        request)
                    log.debug("XACMLAuthzDecisionQuery:\n%s",
                              etree_utils.prettyPrint(requestEtree))
                else:
                    log.error(
                        "Request stored in session is of unknown type: %s" %
                        type(request))

                response = pepCtx.get(
                    SamlPepFilterBase.PEPCTX_RESPONSE_SESSION_KEYNAME)
                if isinstance(response, Response):
                    responseEtree = ResponseElementTree.toXML(response)
                    log.debug("Response:\n%s",
                              etree_utils.prettyPrint(responseEtree))
                else:
                    log.error(
                        "Response stored in session is of unknown type: %s" %
                        type(response))

                timestamp = pepCtx.get(
                    SamlPepFilterBase.PEPCTX_TIMESTAMP_SESSION_KEYNAME)
                log.debug("Timestamp: %s", timestamp)
            log.debug("No PEP context found in session.")
        return self._app(environ, start_response)
Esempio n. 9
0
 def toXML(cls, response, **kw):
     """Extend base method adding mapping for ESG Group/Role Attribute Value 
     to enable ElementTree Attribute Value factory to render the XML output
     
     @type response: ndg.security.common.saml_utils.etree.ESGFGroupRoleAttributeValue
     @param response: ESGF Group/Role attribute value 
     @rtype: ElementTree.Element
     @return: ESGF Group/Role attribute value as ElementTree.Element
     """
     toXMLTypeMap = kw.get('customToXMLTypeMap', {})
     toXMLTypeMap[ESGFGroupRoleAttributeValue
                  ] = ESGFGroupRoleAttributeValueElementTree
     
     kw['customToXMLTypeMap'] = toXMLTypeMap
     
     # Convert to ElementTree representation to enable attachment to SOAP
     # response body
     return ResponseElementTree.toXML(response, **kw)
    def __call__(self, environ, start_response):
        """Logs the request and response stored in the session.

        @type environ: dict
        @param environ: WSGI environment variables dictionary
        @type start_response: function
        @param start_response: standard WSGI start response function
        @rtype: iterable
        @return: response
        """
        session = environ.get('beaker.session.ndg.security')
        if session:
            pepCtx = session.get(SamlPepFilterBase.PEPCTX_SESSION_KEYNAME)
            if pepCtx:
                request = pepCtx.get(SamlPepFilterBase.PEPCTX_REQUEST_SESSION_KEYNAME)
                if isinstance(request, AuthzDecisionQuery):
                    requestEtree = AuthzDecisionQueryElementTree.toXML(request)
                    log.debug("AuthzDecisionQuery:\n%s",
                              etree_utils.prettyPrint(requestEtree))
                elif isinstance(request, XACMLAuthzDecisionQuery):
                    requestEtree = XACMLAuthzDecisionQueryElementTree.toXML(request)
                    log.debug("XACMLAuthzDecisionQuery:\n%s",
                              etree_utils.prettyPrint(requestEtree))
                else:
                    log.error("Request stored in session is of unknown type: %s"
                              % type(request))

                response = pepCtx.get(SamlPepFilterBase.PEPCTX_RESPONSE_SESSION_KEYNAME)
                if isinstance(response, Response):
                    responseEtree = ResponseElementTree.toXML(response)
                    log.debug("Response:\n%s",
                              etree_utils.prettyPrint(responseEtree))
                else:
                    log.error("Response stored in session is of unknown type: %s"
                              % type(response))

                timestamp = pepCtx.get(SamlPepFilterBase.PEPCTX_TIMESTAMP_SESSION_KEYNAME)
                log.debug("Timestamp: %s", timestamp)
            log.debug("No PEP context found in session.")
        return self._app(environ, start_response)
    def __call__(self, environ, start_response):
        soapRequestStream = environ['wsgi.input']
        soapRequest = SOAPEnvelope()
        soapRequest.parse(soapRequestStream)
        attributeQueryElem = soapRequest.body.elem[0]
        attributeQuery = AttributeQueryElementTree.fromXML(attributeQueryElem)
        
        print("Received request from client:\n")
        print soapRequest.prettyPrint()
        
        samlResponse = Response()
        
        samlResponse.issueInstant = datetime.utcnow()
        samlResponse.id = str(uuid4())
        samlResponse.issuer = Issuer()
        
        # SAML 2.0 spec says format must be omitted
        #samlResponse.issuer.format = Issuer.X509_SUBJECT
        samlResponse.issuer.value = \
                        "/O=NDG/OU=BADC/CN=attributeauthority.badc.rl.ac.uk"
        
        samlResponse.inResponseTo = attributeQuery.id
        
        assertion = Assertion()
        
        assertion.version = SAMLVersion(SAMLVersion.VERSION_20)
        assertion.id = str(uuid4())
        assertion.issueInstant = samlResponse.issueInstant
        
        assertion.conditions = Conditions()
        assertion.conditions.notBefore = assertion.issueInstant
        assertion.conditions.notOnOrAfter = assertion.conditions.notBefore + \
            timedelta(seconds=60*60*8)
        
        assertion.subject = Subject()  
        assertion.subject.nameID = NameID()
        assertion.subject.nameID.format = attributeQuery.subject.nameID.format
        assertion.subject.nameID.value = attributeQuery.subject.nameID.value

        assertion.attributeStatements.append(AttributeStatement())
        
        for attribute in attributeQuery.attributes:
            if attribute.name == SamlSoapBindingApp.FIRSTNAME_ATTRNAME:
                # special case handling for 'FirstName' attribute
                fnAttribute = Attribute()
                fnAttribute.name = attribute.name
                fnAttribute.nameFormat = attribute.nameFormat
                fnAttribute.friendlyName = attribute.friendlyName
    
                firstName = XSStringAttributeValue()
                firstName.value = self.firstName
                fnAttribute.attributeValues.append(firstName)
    
                assertion.attributeStatements[0].attributes.append(fnAttribute)
            
            elif attribute.name == SamlSoapBindingApp.LASTNAME_ATTRNAME:
                lnAttribute = Attribute()
                lnAttribute.name = attribute.name
                lnAttribute.nameFormat = attribute.nameFormat
                lnAttribute.friendlyName = attribute.friendlyName
    
                lastName = XSStringAttributeValue()
                lastName.value = self.lastName
                lnAttribute.attributeValues.append(lastName)
    
                assertion.attributeStatements[0].attributes.append(lnAttribute)
               
            elif attribute.name == SamlSoapBindingApp.EMAILADDRESS_ATTRNAME:
                emailAddressAttribute = Attribute()
                emailAddressAttribute.name = attribute.name
                emailAddressAttribute.nameFormat = attribute.nameFormat
                emailAddressAttribute.friendlyName = attribute.friendlyName
    
                emailAddress = XSStringAttributeValue()
                emailAddress.value = self.emailAddress
                emailAddressAttribute.attributeValues.append(emailAddress)
    
                assertion.attributeStatements[0].attributes.append(
                                                        emailAddressAttribute)
        
        samlResponse.assertions.append(assertion)
        
        samlResponse.status = Status()
        samlResponse.status.statusCode = StatusCode()
        samlResponse.status.statusCode.value = StatusCode.SUCCESS_URI        

        
        # Convert to ElementTree representation to enable attachment to SOAP
        # response body
        samlResponseElem = ResponseElementTree.toXML(samlResponse)
        xml = ElementTree.tostring(samlResponseElem)
        log.debug('Sending response to query:\n%s', xml)
        
        # Create SOAP response and attach the SAML Response payload
        soapResponse = SOAPEnvelope()
        soapResponse.create()
        soapResponse.body.elem.append(samlResponseElem)
        
        response = soapResponse.serialize()
        
        start_response("200 OK",
                       [('Content-length', str(len(response))),
                        ('Content-type', 'text/xml')])
        return [response]