def create_authz_decision_query_response(cls): """Helper method for Authz Decision Response""" response = Response() now = datetime.utcnow() response.issueInstant = now # Make up a request ID that this response is responding to response.inResponseTo = str(uuid4()) response.id = str(uuid4()) response.version = SAMLVersion(SAMLVersion.VERSION_20) response.issuer = Issuer() response.issuer.format = Issuer.X509_SUBJECT response.issuer.value = cls.ISSUER_DN response.status = Status() response.status.statusCode = StatusCode() response.status.statusCode.value = StatusCode.SUCCESS_URI response.status.statusMessage = StatusMessage() response.status.statusMessage.value = "Response created successfully" assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = now authzDecisionStatement = AuthzDecisionStatement() authzDecisionStatement.decision = DecisionType.PERMIT authzDecisionStatement.resource = cls.RESOURCE_URI authzDecisionStatement.actions.append(Action()) authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI authzDecisionStatement.actions[-1].value = Action.HTTP_GET_ACTION assertion.authzDecisionStatements.append(authzDecisionStatement) # Add a conditions statement for a validity of 8 hours assertion.conditions = Conditions() assertion.conditions.notBefore = now assertion.conditions.notOnOrAfter = now + timedelta(seconds=60*60*8) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = cls.NAMEID_FORMAT assertion.subject.nameID.value = cls.NAMEID_VALUE assertion.issuer = Issuer() assertion.issuer.format = Issuer.X509_SUBJECT assertion.issuer.value = cls.ISSUER_DN response.assertions.append(assertion) return response
def authzDecisionQuery(query, response): now = datetime.utcnow() response.issueInstant = now # Make up a request ID that this response is responding to response.inResponseTo = query.id response.id = str(uuid4()) response.version = SAMLVersion(SAMLVersion.VERSION_20) response.status = Status() response.status.statusCode = StatusCode() response.status.statusCode.value = StatusCode.SUCCESS_URI response.status.statusMessage = StatusMessage() response.status.statusMessage.value = \ "Response created successfully" assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = now authzDecisionStatement = AuthzDecisionStatement() authzDecisionStatement.decision = DecisionType.PERMIT authzDecisionStatement.resource = \ TestAuthorisationServiceMiddleware.RESOURCE_URI authzDecisionStatement.actions.append(Action()) authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI authzDecisionStatement.actions[-1].value = Action.HTTP_GET_ACTION assertion.authzDecisionStatements.append(authzDecisionStatement) # Add a conditions statement for a validity of 8 hours assertion.conditions = Conditions() assertion.conditions.notBefore = now assertion.conditions.notOnOrAfter = now + timedelta(seconds=60 * 60 * 8) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = query.subject.nameID.format assertion.subject.nameID.value = query.subject.nameID.value assertion.issuer = Issuer() assertion.issuer.format = Issuer.X509_SUBJECT assertion.issuer.value = \ TestAuthorisationServiceMiddleware.ISSUER_DN response.assertions.append(assertion) return response
def authzDecisionQuery(query, response): now = datetime.utcnow() response.issueInstant = now # Make up a request ID that this response is responding to response.inResponseTo = query.id response.id = str(uuid4()) response.version = SAMLVersion(SAMLVersion.VERSION_20) response.status = Status() response.status.statusCode = StatusCode() response.status.statusCode.value = StatusCode.SUCCESS_URI response.status.statusMessage = StatusMessage() response.status.statusMessage.value = \ "Response created successfully" assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = now authzDecisionStatement = AuthzDecisionStatement() authzDecisionStatement.decision = DecisionType.PERMIT authzDecisionStatement.resource = \ TestAuthorisationServiceMiddleware.RESOURCE_URI authzDecisionStatement.actions.append(Action()) authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI authzDecisionStatement.actions[-1].value = Action.HTTP_GET_ACTION assertion.authzDecisionStatements.append(authzDecisionStatement) # Add a conditions statement for a validity of 8 hours assertion.conditions = Conditions() assertion.conditions.notBefore = now assertion.conditions.notOnOrAfter = now + timedelta(seconds=60*60*8) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = query.subject.nameID.format assertion.subject.nameID.value = query.subject.nameID.value assertion.issuer = Issuer() assertion.issuer.format = Issuer.X509_SUBJECT assertion.issuer.value = \ TestAuthorisationServiceMiddleware.ISSUER_DN response.assertions.append(assertion) return response
def attributeQuery(query, response): """Attribute Query interface called by the next middleware in the stack the SAML SOAP Query interface middleware instance (ndg.saml.saml2.binding.soap.server.wsgi.queryinterface.SOAPQueryInterfaceMiddleware) """ response.issueInstant = datetime.utcnow() response.id = str(uuid4()) response.inResponseTo = query.id if query.issuer.value not in self.__class__.VALID_QUERY_ISSUERS: response.status.statusCode.value = \ StatusCode.REQUEST_DENIED_URI response.status.statusMessage.value = 'Invalid issuer' return response if query.subject.nameID.value not in self.__class__.VALID_SUBJECTS: response.status.statusCode.value = \ StatusCode.UNKNOWN_PRINCIPAL_URI response.status.statusMessage.value = 'Unknown user' return response assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = response.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 = query.subject.nameID.format assertion.subject.nameID.value = query.subject.nameID.value assertion.attributeStatements.append(AttributeStatement()) for attribute in query.attributes: if attribute.name == self.__class__.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 == self.__class__.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 == self.__class__.EMAILADDRESS_ATTRNAME and query.issuer.value == self.__class__.VALID_QUERY_ISSUERS[0]): 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) else: response.status.statusCode.value = \ StatusCode.INVALID_ATTR_NAME_VALUE_URI return response response.assertions.append(assertion) response.status.statusCode.value = StatusCode.SUCCESS_URI return response
def authzDecisionQuery(query, response): """Authorisation Decision Query interface called by the next middleware in the stack the SAML SOAP Query interface middleware instance (ndg.saml.saml2.binding.soap.server.wsgi.queryinterface.SOAPQueryInterfaceMiddleware) """ now = datetime.utcnow() response.issueInstant = now # Make up a request ID that this response is responding to response.inResponseTo = query.id response.id = str(uuid4()) response.version = SAMLVersion(SAMLVersion.VERSION_20) response.status = Status() response.status.statusCode = StatusCode() response.status.statusCode.value = StatusCode.SUCCESS_URI response.status.statusMessage = StatusMessage() response.status.statusMessage.value = \ "Response created successfully" assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = now authzDecisionStatement = AuthzDecisionStatement() # Make some simple logic to simulate a full access policy if query.resource == self.__class__.RESOURCE_URI: if query.actions[0].value == Action.HTTP_GET_ACTION: authzDecisionStatement.decision = DecisionType.PERMIT else: authzDecisionStatement.decision = DecisionType.DENY else: authzDecisionStatement.decision = DecisionType.INDETERMINATE authzDecisionStatement.resource = query.resource authzDecisionStatement.actions.append(Action()) authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI authzDecisionStatement.actions[-1].value = Action.HTTP_GET_ACTION assertion.authzDecisionStatements.append(authzDecisionStatement) # Add a conditions statement for a validity of 8 hours assertion.conditions = Conditions() assertion.conditions.notBefore = now assertion.conditions.notOnOrAfter = now + timedelta(seconds=60*60*8) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = query.subject.nameID.format assertion.subject.nameID.value = query.subject.nameID.value assertion.issuer = Issuer() assertion.issuer.format = Issuer.X509_SUBJECT assertion.issuer.value = \ TestAuthorisationServiceMiddleware.ISSUER_DN response.assertions.append(assertion) return response
def getAttributes(self, attributeQuery, response): """Attribute Authority SAML AttributeQuery @type attributeQuery: saml.saml2.core.AttributeQuery @param userId: query containing requested attributes @type response: saml.saml2.core.Response @param response: add an assertion with the list of attributes for the given subject ID in the query or set an error Status code and message @raise AttributeInterfaceError: an error occured requesting attributes @raise AttributeReleaseDeniedError: Requestor was denied release of the requested attributes @raise AttributeNotKnownError: Requested attribute names are not known to this authority """ userId = attributeQuery.subject.nameID.value requestedAttributeNames = [attribute.name for attribute in attributeQuery.attributes] requestorDN = X500DN.from_string(attributeQuery.issuer.value) if not self._queryDbForSamlSubject(userId): raise UserIdNotKnown('Subject Id "%s" is not known to this ' 'authority' % userId) if (len(self.samlValidRequestorDNs) > 0 and requestorDN not in self.samlValidRequestorDNs): raise InvalidRequestorId('Requester identity "%s" is invalid' % requestorDN) unknownAttrNames = [attrName for attrName in requestedAttributeNames if attrName not in self.__samlAttribute2SqlQuery] if len(unknownAttrNames) > 0: raise AttributeNotKnownError("Unknown attributes requested: %r" % unknownAttrNames) # Create a new assertion to hold the attributes to be returned assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = response.issueInstant # Assumes SAML response issuer details as set by - # ndg.security.server.wsgi.saml.SOAPQueryInterfaceMiddleware assertion.issuer = Issuer() assertion.issuer.value = response.issuer.value if response.issuer.format: assertion.issuer.format = response.issuer.format assertion.conditions = Conditions() assertion.conditions.notBefore = assertion.issueInstant assertion.conditions.notOnOrAfter = (assertion.conditions.notBefore + self.samlAssertionLifetime) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = attributeQuery.subject.nameID.format assertion.subject.nameID.value = attributeQuery.subject.nameID.value attributeStatement = AttributeStatement() # Query the database for the requested attributes and return them # mapped to their attribute names as specified by the attributeNames # property for requestedAttribute in attributeQuery.attributes: attributeVals = self._queryDbForSamlAttributes( requestedAttribute.name, userId) # Make a new SAML attribute object to hold the values obtained attribute = Attribute() attribute.name = requestedAttribute.name attribute.nameFormat = requestedAttribute.nameFormat if requestedAttribute.friendlyName is not None: attribute.friendlyName = requestedAttribute.friendlyName # Call specific conversion utility to convert the retrieved field # to the correct SAML attribute value type try: field2SamlAttributeVal = self.__samlAttribute2SqlQuery[ requestedAttribute.name][-1] except (IndexError, TypeError) as e: raise AttributeInterfaceConfigError('Bad format for SAML ' 'attribute to SQL query ' 'look-up for attribute ' 'name %r: %s' % (requestedAttribute.name, e)) for val in attributeVals: attributeValue = field2SamlAttributeVal(val) attribute.attributeValues.append(attributeValue) attributeStatement.attributes.append(attribute) assertion.attributeStatements.append(attributeStatement) response.assertions.append(assertion)
def getAttributes(self, attributeQuery, response): '''Test Attribute Authority SAML Attribute Query interface''' userId = attributeQuery.subject.nameID.value requestedAttributeNames = [attribute.name for attribute in attributeQuery.attributes] if attributeQuery.issuer.format != Issuer.X509_SUBJECT: raise InvalidRequestorId('Requestor issuer format "%s" is invalid' % attributeQuery.issuerFormat.value) requestorId = X500DN.fromString(attributeQuery.issuer.value) if userId not in TestUserRoles.VALID_USER_IDS: raise UserIdNotKnown('Subject Id "%s" is not known to this ' 'authority' % userId) if requestorId not in TestUserRoles.VALID_REQUESTOR_IDS: raise InvalidRequestorId('Requestor identity "%s" is invalid' % requestorId) unknownAttrNames = [attrName for attrName in requestedAttributeNames if attrName not in TestUserRoles.SAML_ATTRIBUTE_NAMES] if len(unknownAttrNames) > 0: raise AttributeNotKnownError("Unknown attributes requested: %r" % unknownAttrNames) if requestorId == TestUserRoles.INSUFFICIENT_PRIVILEGES_REQUESTOR_ID: raise AttributeReleaseDenied("Attribute release denied for the " 'requestor "%s"' % requestorId) # Create a new assertion to hold the attributes to be returned assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = response.issueInstant assertion.issuer = Issuer() assertion.issuer.value = response.issuer.value assertion.issuer.format = Issuer.X509_SUBJECT assertion.conditions = Conditions() assertion.conditions.notBefore = assertion.issueInstant assertion.conditions.notOnOrAfter = assertion.conditions.notBefore + \ timedelta(seconds=TestUserRoles.SAML_ASSERTION_LIFETIME) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = attributeQuery.subject.nameID.format assertion.subject.nameID.value = attributeQuery.subject.nameID.value attributeStatement = AttributeStatement() # Add test set of attributes for name in requestedAttributeNames: attributeFound = False for attribute in TestUserRoles.SAML_ATTRIBUTES: if attribute.name == name: attributeFound = True break if attributeFound: attributeStatement.attributes.append(attribute) else: raise AttributeNotKnownError("Unknown attribute requested: %s"% name) assertion.attributeStatements.append(attributeStatement) response.assertions.append(assertion)
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]
def authzDecisionQuery(query, response): """Authorisation Decision Query interface called by the next middleware in the stack the SAML SOAP Query interface middleware instance (ndg.saml.saml2.binding.soap.server.wsgi.queryinterface.SOAPQueryInterfaceMiddleware) """ now = datetime.utcnow() response.issueInstant = now # Make up a request ID that this response is responding to response.inResponseTo = query.id response.id = str(uuid4()) response.version = SAMLVersion(SAMLVersion.VERSION_20) response.status = Status() response.status.statusCode = StatusCode() response.status.statusCode.value = StatusCode.SUCCESS_URI response.status.statusMessage = StatusMessage() response.status.statusMessage.value = \ "Response created successfully" assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = now authzDecisionStatement = AuthzDecisionStatement() # Make some simple logic to simulate a full access policy if query.resource == self.__class__.RESOURCE_URI: if query.actions[0].value == Action.HTTP_GET_ACTION: authzDecisionStatement.decision = DecisionType.PERMIT else: authzDecisionStatement.decision = DecisionType.DENY else: authzDecisionStatement.decision = DecisionType.INDETERMINATE authzDecisionStatement.resource = query.resource authzDecisionStatement.actions.append(Action()) authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI authzDecisionStatement.actions[-1].value = Action.HTTP_GET_ACTION assertion.authzDecisionStatements.append(authzDecisionStatement) # Add a conditions statement for a validity of 8 hours assertion.conditions = Conditions() assertion.conditions.notBefore = now assertion.conditions.notOnOrAfter = now + timedelta(seconds=60 * 60 * 8) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = query.subject.nameID.format assertion.subject.nameID.value = query.subject.nameID.value assertion.issuer = Issuer() assertion.issuer.format = Issuer.X509_SUBJECT assertion.issuer.value = \ TestAuthorisationServiceMiddleware.ISSUER_DN response.assertions.append(assertion) return response
def getAttributes(self, attributeQuery, response): '''Test Attribute Authority SAML Attribute Query interface''' userId = attributeQuery.subject.nameID.value requestedAttributeNames = [ attribute.name for attribute in attributeQuery.attributes ] if attributeQuery.issuer.format != Issuer.X509_SUBJECT: raise InvalidRequestorId( 'Requestor issuer format "%s" is invalid' % attributeQuery.issuerFormat.value) requestorId = X500DN.fromString(attributeQuery.issuer.value) if userId not in TestUserRoles.VALID_USER_IDS: raise UserIdNotKnown('Subject Id "%s" is not known to this ' 'authority' % userId) if requestorId not in TestUserRoles.VALID_REQUESTOR_IDS: raise InvalidRequestorId('Requestor identity "%s" is invalid' % requestorId) unknownAttrNames = [ attrName for attrName in requestedAttributeNames if attrName not in TestUserRoles.SAML_ATTRIBUTE_NAMES ] if len(unknownAttrNames) > 0: raise AttributeNotKnownError("Unknown attributes requested: %r" % unknownAttrNames) if requestorId == TestUserRoles.INSUFFICIENT_PRIVILEGES_REQUESTOR_ID: raise AttributeReleaseDenied("Attribute release denied for the " 'requestor "%s"' % requestorId) # Create a new assertion to hold the attributes to be returned assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = response.issueInstant assertion.issuer = Issuer() assertion.issuer.value = response.issuer.value assertion.issuer.format = Issuer.X509_SUBJECT assertion.conditions = Conditions() assertion.conditions.notBefore = assertion.issueInstant assertion.conditions.notOnOrAfter = assertion.conditions.notBefore + \ timedelta(seconds=TestUserRoles.SAML_ASSERTION_LIFETIME) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = attributeQuery.subject.nameID.format assertion.subject.nameID.value = attributeQuery.subject.nameID.value attributeStatement = AttributeStatement() # Add test set of attributes for name in requestedAttributeNames: attributeFound = False for attribute in TestUserRoles.SAML_ATTRIBUTES: if attribute.name == name: attributeFound = True break if attributeFound: attributeStatement.attributes.append(attribute) else: raise AttributeNotKnownError( "Unknown attribute requested: %s" % name) assertion.attributeStatements.append(attributeStatement) response.assertions.append(assertion)
def getAttributes(self, attributeQuery, response): """Attribute Authority SAML AttributeQuery @type attributeQuery: saml.saml2.core.AttributeQuery @param userId: query containing requested attributes @type response: saml.saml2.core.Response @param response: add an assertion with the list of attributes for the given subject ID in the query or set an error Status code and message @raise AttributeInterfaceError: an error occured requesting attributes @raise AttributeReleaseDeniedError: Requestor was denied release of the requested attributes @raise AttributeNotKnownError: Requested attribute names are not known to this authority """ userId = attributeQuery.subject.nameID.value requestedAttributeNames = [ attribute.name for attribute in attributeQuery.attributes ] requestorDN = X500DN.from_string(attributeQuery.issuer.value) if not self._queryDbForSamlSubject(userId): raise UserIdNotKnown('Subject Id "%s" is not known to this ' 'authority' % userId) if (len(self.samlValidRequestorDNs) > 0 and requestorDN not in self.samlValidRequestorDNs): raise InvalidRequestorId('Requester identity "%s" is invalid' % requestorDN) unknownAttrNames = [ attrName for attrName in requestedAttributeNames if attrName not in self.__samlAttribute2SqlQuery ] if len(unknownAttrNames) > 0: raise AttributeNotKnownError("Unknown attributes requested: %r" % unknownAttrNames) # Create a new assertion to hold the attributes to be returned assertion = Assertion() assertion.version = SAMLVersion(SAMLVersion.VERSION_20) assertion.id = str(uuid4()) assertion.issueInstant = response.issueInstant # Assumes SAML response issuer details as set by - # ndg.security.server.wsgi.saml.SOAPQueryInterfaceMiddleware assertion.issuer = Issuer() assertion.issuer.value = response.issuer.value if response.issuer.format: assertion.issuer.format = response.issuer.format assertion.conditions = Conditions() assertion.conditions.notBefore = assertion.issueInstant assertion.conditions.notOnOrAfter = (assertion.conditions.notBefore + self.samlAssertionLifetime) assertion.subject = Subject() assertion.subject.nameID = NameID() assertion.subject.nameID.format = attributeQuery.subject.nameID.format assertion.subject.nameID.value = attributeQuery.subject.nameID.value attributeStatement = AttributeStatement() # Query the database for the requested attributes and return them # mapped to their attribute names as specified by the attributeNames # property for requestedAttribute in attributeQuery.attributes: attributeVals = self._queryDbForSamlAttributes( requestedAttribute.name, userId) # Make a new SAML attribute object to hold the values obtained attribute = Attribute() attribute.name = requestedAttribute.name attribute.nameFormat = requestedAttribute.nameFormat if requestedAttribute.friendlyName is not None: attribute.friendlyName = requestedAttribute.friendlyName # Call specific conversion utility to convert the retrieved field # to the correct SAML attribute value type try: field2SamlAttributeVal = self.__samlAttribute2SqlQuery[ requestedAttribute.name][-1] except (IndexError, TypeError) as e: raise AttributeInterfaceConfigError( 'Bad format for SAML ' 'attribute to SQL query ' 'look-up for attribute ' 'name %r: %s' % (requestedAttribute.name, e)) for val in attributeVals: attributeValue = field2SamlAttributeVal(val) attribute.attributeValues.append(attributeValue) attributeStatement.attributes.append(attribute) assertion.attributeStatements.append(attributeStatement) response.assertions.append(assertion)