Skip to content

Commit c12b178

Browse files
committed
IdP metadata parser: add required_sso/slo_binding parameters
- By default, extract urls for REDIRECT binding (as before) - Include `binding` key in resulting settings dictionary - Adjust docstring to reflect new behavior
1 parent 43ff778 commit c12b178

1 file changed

Lines changed: 45 additions & 10 deletions

File tree

src/onelogin/saml2/idp_metadata_parser.py

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def get_metadata(url):
4848
return xml
4949

5050
@staticmethod
51-
def parse_remote(url):
51+
def parse_remote(url, **kwargs):
5252
"""
5353
Get the metadata XML from the provided URL and parse it, returning a dict with extracted data
5454
:param url: Url where the XML of the Identity Provider Metadata is published.
@@ -57,19 +57,41 @@ def parse_remote(url):
5757
:rtype: dict
5858
"""
5959
idp_metadata = OneLogin_Saml2_IdPMetadataParser.get_metadata(url)
60-
return OneLogin_Saml2_IdPMetadataParser.parse(idp_metadata)
60+
return OneLogin_Saml2_IdPMetadataParser.parse(idp_metadata, **kwargs)
6161

6262
@staticmethod
63-
def parse(idp_metadata):
63+
def parse(
64+
idp_metadata,
65+
required_sso_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT,
66+
required_slo_binding=OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT):
6467
"""
65-
Parse the Identity Provider metadata and returns a dict with extracted data
66-
If there are multiple IDPSSODescriptor it will only parse the first
68+
Parse the Identity Provider metadata and return a dict with extracted data.
69+
70+
If there are multiple <IDPSSODescriptor> tags, parse only the first.
71+
72+
Parse only those SSO endpoints with the same binding as given by
73+
the `required_sso_binding` parameter.
74+
75+
Parse only those SLO endpoints with the same binding as given by
76+
the `required_slo_binding` parameter.
77+
78+
If the metadata specifies multiple SSO endpoints with the required
79+
binding, extract only the first (the same holds true for SLO
80+
endpoints).
81+
6782
:param idp_metadata: XML of the Identity Provider Metadata.
6883
:type idp_metadata: string
69-
:param url: If true and the URL is HTTPs, the cert of the domain is checked.
70-
:type url: bool
84+
85+
:param required_sso_binding: Parse only POST or REDIRECT SSO endpoints.
86+
:type required_sso_binding: one of OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
87+
or OneLogin_Saml2_Constants.BINDING_HTTP_POST
88+
89+
:param required_slo_binding: Parse only POST or REDIRECT SLO endpoints.
90+
:type required_slo_binding: one of OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT
91+
or OneLogin_Saml2_Constants.BINDING_HTTP_POST
92+
7193
:returns: settings dict with extracted data
72-
:rtype: string
94+
:rtype: dict
7395
"""
7496
data = {}
7597

@@ -92,11 +114,19 @@ def parse(idp_metadata):
92114
if len(name_id_format_nodes) > 0:
93115
idp_name_id_format = name_id_format_nodes[0].text
94116

95-
sso_nodes = OneLogin_Saml2_XML.query(idp_descriptor_node, "./md:SingleSignOnService[@Binding='%s']" % OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT)
117+
sso_nodes = OneLogin_Saml2_XML.query(
118+
idp_descriptor_node,
119+
"./md:SingleSignOnService[@Binding='%s']" % required_sso_binding
120+
)
121+
96122
if len(sso_nodes) > 0:
97123
idp_sso_url = sso_nodes[0].get('Location', None)
98124

99-
slo_nodes = OneLogin_Saml2_XML.query(idp_descriptor_node, "./md:SingleLogoutService[@Binding='%s']" % OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT)
125+
slo_nodes = OneLogin_Saml2_XML.query(
126+
idp_descriptor_node,
127+
"./md:SingleLogoutService[@Binding='%s']" % required_slo_binding
128+
)
129+
100130
if len(slo_nodes) > 0:
101131
idp_slo_url = slo_nodes[0].get('Location', None)
102132

@@ -108,12 +138,17 @@ def parse(idp_metadata):
108138

109139
if idp_entity_id is not None:
110140
data['idp']['entityId'] = idp_entity_id
141+
111142
if idp_sso_url is not None:
112143
data['idp']['singleSignOnService'] = {}
113144
data['idp']['singleSignOnService']['url'] = idp_sso_url
145+
data['idp']['singleSignOnService']['binding'] = required_sso_binding
146+
114147
if idp_slo_url is not None:
115148
data['idp']['singleLogoutService'] = {}
116149
data['idp']['singleLogoutService']['url'] = idp_slo_url
150+
data['idp']['singleLogoutService']['binding'] = required_slo_binding
151+
117152
if idp_x509_cert is not None:
118153
data['idp']['x509cert'] = idp_x509_cert
119154

0 commit comments

Comments
 (0)