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))
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
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
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)
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
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 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]