Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
:param xml: Encrypted Assertion
:type xml: Element
:returns: Decrypted Assertion
:rtype: Element
"""
key = self.__settings.get_sp_key()
debug = self.__settings.is_debug_active()
if not key:
raise Exception('No private key available, check settings')
encrypted_assertion_nodes = OneLogin_Saml2_XML.query(xml, '/samlp:Response/saml:EncryptedAssertion')
if encrypted_assertion_nodes:
encrypted_data_nodes = OneLogin_Saml2_XML.query(encrypted_assertion_nodes[0], '//saml:EncryptedAssertion/xenc:EncryptedData')
if encrypted_data_nodes:
keyinfo = OneLogin_Saml2_XML.query(encrypted_assertion_nodes[0], '//saml:EncryptedAssertion/xenc:EncryptedData/ds:KeyInfo')
if not keyinfo:
raise Exception('No KeyInfo present, invalid Assertion')
keyinfo = keyinfo[0]
children = keyinfo.getchildren()
if not children:
raise Exception('No child to KeyInfo, invalid Assertion')
for child in children:
if 'RetrievalMethod' in child.tag:
if child.attrib['Type'] != 'http://www.w3.org/2001/04/xmlenc#EncryptedKey':
raise Exception('Unsupported Retrieval Method found')
uri = child.attrib['URI']
if not uri.startswith('#'):
break
uri = uri.split('#')[1]
encrypted_key = OneLogin_Saml2_XML.query(encrypted_assertion_nodes[0], './xenc:EncryptedKey[@Id="' + uri + '"]')
if encrypted_key:
dom = OneLogin_Saml2_XML.to_etree(idp_metadata)
entity_descriptor_nodes = OneLogin_Saml2_XML.query(dom, '//md:EntityDescriptor')
idp_entity_id = want_authn_requests_signed = idp_name_id_format = idp_sso_url = idp_slo_url = idp_x509_cert = None
if len(entity_descriptor_nodes) > 0:
for entity_descriptor_node in entity_descriptor_nodes:
idp_descriptor_nodes = OneLogin_Saml2_XML.query(entity_descriptor_node, './md:IDPSSODescriptor')
if len(idp_descriptor_nodes) > 0:
idp_descriptor_node = idp_descriptor_nodes[0]
idp_entity_id = entity_descriptor_node.get('entityID', None)
want_authn_requests_signed = entity_descriptor_node.get('WantAuthnRequestsSigned', None)
name_id_format_nodes = OneLogin_Saml2_XML.query(idp_descriptor_node, './md:NameIDFormat')
if len(name_id_format_nodes) > 0:
idp_name_id_format = name_id_format_nodes[0].text
sso_nodes = OneLogin_Saml2_XML.query(
idp_descriptor_node,
"./md:SingleSignOnService[@Binding='%s']" % required_sso_binding
)
if len(sso_nodes) > 0:
idp_sso_url = sso_nodes[0].get('Location', None)
slo_nodes = OneLogin_Saml2_XML.query(
idp_descriptor_node,
"./md:SingleLogoutService[@Binding='%s']" % required_slo_binding
)
:type idp_metadata: string
:param required_sso_binding: Parse only POST or REDIRECT SSO endpoints.
:type required_sso_binding: one of OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
or OneLogin_Saml2_Constants.BINDING_HTTP_POST
:param required_slo_binding: Parse only POST or REDIRECT SLO endpoints.
:type required_slo_binding: one of OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
or OneLogin_Saml2_Constants.BINDING_HTTP_POST
:returns: settings dict with extracted data
:rtype: dict
"""
data = {}
dom = OneLogin_Saml2_XML.to_etree(idp_metadata)
entity_descriptor_nodes = OneLogin_Saml2_XML.query(dom, '//md:EntityDescriptor')
idp_entity_id = want_authn_requests_signed = idp_name_id_format = idp_sso_url = idp_slo_url = idp_x509_cert = None
if len(entity_descriptor_nodes) > 0:
for entity_descriptor_node in entity_descriptor_nodes:
idp_descriptor_nodes = OneLogin_Saml2_XML.query(entity_descriptor_node, './md:IDPSSODescriptor')
if len(idp_descriptor_nodes) > 0:
idp_descriptor_node = idp_descriptor_nodes[0]
idp_entity_id = entity_descriptor_node.get('entityID', None)
want_authn_requests_signed = entity_descriptor_node.get('WantAuthnRequestsSigned', None)
name_id_format_nodes = OneLogin_Saml2_XML.query(idp_descriptor_node, './md:NameIDFormat')
if len(name_id_format_nodes) > 0:
def get_id(request):
"""
Returns the ID of the Logout Request
:param request: Logout Request Message
:type request: string|DOMDocument
:return: string ID
:rtype: str object
"""
elem = OneLogin_Saml2_XML.to_etree(request)
return elem.get('ID', None)
def __init__(self, settings, response):
"""
Constructs the response object.
:param settings: The setting info
:type settings: OneLogin_Saml2_Setting object
:param response: The base64 encoded, XML string containing the samlp:Response
:type response: string
"""
self.__settings = settings
self.__error = None
self.response = OneLogin_Saml2_Utils.b64decode(response)
self.document = OneLogin_Saml2_XML.to_etree(self.response)
self.decrypted_document = None
self.encrypted = None
# Quick check for the presence of EncryptedAssertion
encrypted_assertion_nodes = self.__query('/samlp:Response/saml:EncryptedAssertion')
if encrypted_assertion_nodes:
decrypted_document = deepcopy(self.document)
self.encrypted = True
self.decrypted_document = self.__decrypt_assertion(decrypted_document)
def get_metadata(url):
"""
Get the metadata XML from the provided URL
:param url: Url where the XML of the Identity Provider Metadata is published.
:type url: string
:returns: metadata XML
:rtype: string
"""
valid = False
response = urllib2.urlopen(url)
xml = response.read()
if xml:
try:
dom = OneLogin_Saml2_XML.to_etree(xml)
idp_descriptor_nodes = OneLogin_Saml2_XML.query(dom, '//md:IDPSSODescriptor')
if idp_descriptor_nodes:
valid = True
except:
pass
if not valid:
raise Exception('Not valid IdP XML found from URL: %s' % (url))
return xml
def is_valid(self, request_data, request_id=None):
"""
Determines if the SAML LogoutResponse is valid
:param request_id: The ID of the LogoutRequest sent by this SP to the IdP
:type request_id: string
:return: Returns if the SAML LogoutResponse is or not valid
:rtype: boolean
"""
self.__error = None
try:
idp_data = self.__settings.get_idp_data()
idp_entity_id = idp_data['entityId']
get_data = request_data['get_data']
if self.__settings.is_strict():
res = OneLogin_Saml2_XML.validate_xml(self.document, 'saml-schema-protocol-2.0.xsd', self.__settings.is_debug_active())
if isinstance(res, str):
raise Exception('Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd')
security = self.__settings.get_security_data()
# Check if the InResponseTo of the Logout Response matchs the ID of the Logout Request (requestId) if provided
in_response_to = self.document.get('InResponseTo', None)
if request_id is not None and in_response_to and in_response_to != request_id:
raise Exception('The InResponseTo of the Logout Response: %s, does not match the ID of the Logout request sent by the SP: %s' % (in_response_to, request_id))
# Check issuer
issuer = self.get_issuer()
if issuer is not None and issuer != idp_entity_id:
raise Exception('Invalid issuer in the Logout Request')
current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)
:type: string
:param cert: IdP Public Cert to encrypt the nameID
:type: string
:param debug: Activate the xmlsec debug
:type: bool
:returns: DOMElement | XMLSec nameID
:rtype: string
:param nq: IDP Name Qualifier
:type: string
"""
root = OneLogin_Saml2_XML.make_root("{%s}container" % OneLogin_Saml2_Constants.NS_SAML)
name_id = OneLogin_Saml2_XML.make_child(root, '{%s}NameID' % OneLogin_Saml2_Constants.NS_SAML)
if sp_nq is not None:
name_id.set('SPNameQualifier', sp_nq)
name_id.set('Format', sp_format)
if nq is not None:
name_id.set('NameQualifier', nq)
name_id.text = value
if cert is not None:
xmlsec.enable_debug_trace(debug)
# Load the public cert
manager = xmlsec.KeysManager()
manager.add_key(xmlsec.Key.from_memory(cert, xmlsec.KeyFormat.CERT_PEM, None))
# Prepare for encryption
def validate_num_assertions(self):
"""
Verifies that the document only contains a single Assertion (encrypted or not)
:returns: True if only 1 assertion encrypted or not
:rtype: bool
"""
encrypted_assertion_nodes = OneLogin_Saml2_XML.query(self.document, '//saml:EncryptedAssertion')
assertion_nodes = OneLogin_Saml2_XML.query(self.document, '//saml:Assertion')
return (len(encrypted_assertion_nodes) + len(assertion_nodes)) == 1
def get_issuer(request):
"""
Gets the Issuer of the Logout Request Message
:param request: Logout Request Message
:type request: string|DOMDocument
:return: The Issuer
:rtype: string
"""
elem = OneLogin_Saml2_XML.to_etree(request)
issuer = None
issuer_nodes = OneLogin_Saml2_XML.query(elem, '/samlp:LogoutRequest/saml:Issuer')
if len(issuer_nodes) == 1:
issuer = issuer_nodes[0].text
return issuer