Skip to content

Commit 9e0f8af

Browse files
authored
Merge pull request #407 from cemiarni/master
Fix some ECP problems
2 parents 91bce29 + d99bee3 commit 9e0f8af

File tree

4 files changed

+55
-43
lines changed

4 files changed

+55
-43
lines changed

src/saml2/ecp.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
from saml2.response import authn_response
2626

27+
from saml2 import saml
28+
2729
logger = logging.getLogger(__name__)
2830

2931

@@ -53,7 +55,7 @@ def ecp_auth_request(cls, entityid=None, relay_state="", sign=False):
5355
# ----------------------------------------
5456
# <paos:Request>
5557
# ----------------------------------------
56-
my_url = cls.service_url(BINDING_PAOS)
58+
my_url = cls.service_urls(BINDING_PAOS)[0]
5759

5860
# must_understand and actor according to the standard
5961
#
@@ -63,6 +65,19 @@ def ecp_auth_request(cls, entityid=None, relay_state="", sign=False):
6365

6466
eelist.append(element_to_extension_element(paos_request))
6567

68+
# ----------------------------------------
69+
# <samlp:AuthnRequest>
70+
# ----------------------------------------
71+
72+
logger.info("entityid: %s, binding: %s" % (entityid, BINDING_SOAP))
73+
74+
location = cls._sso_location(entityid, binding=BINDING_SOAP)
75+
req_id, authn_req = cls.create_authn_request(
76+
location, binding=BINDING_PAOS, service_url_binding=BINDING_PAOS)
77+
78+
body = soapenv.Body()
79+
body.extension_elements = [element_to_extension_element(authn_req)]
80+
6681
# ----------------------------------------
6782
# <ecp:Request>
6883
# ----------------------------------------
@@ -74,14 +89,16 @@ def ecp_auth_request(cls, entityid=None, relay_state="", sign=False):
7489
# )
7590
#
7691
# idp_list = samlp.IDPList(idp_entry= [idp])
77-
#
78-
# ecp_request = ecp.Request(
79-
# actor = ACTOR, must_understand = "1",
80-
# provider_name = "Example Service Provider",
81-
# issuer=saml.Issuer(text="https://sp.example.org/entity"),
82-
# idp_list = idp_list)
83-
#
84-
# eelist.append(element_to_extension_element(ecp_request))
92+
93+
idp_list = None
94+
ecp_request = ecp.Request(
95+
actor=ACTOR,
96+
must_understand="1",
97+
provider_name=None,
98+
issuer=saml.Issuer(text=authn_req.issuer.text),
99+
idp_list=idp_list)
100+
101+
eelist.append(element_to_extension_element(ecp_request))
85102

86103
# ----------------------------------------
87104
# <ecp:RelayState>
@@ -95,19 +112,6 @@ def ecp_auth_request(cls, entityid=None, relay_state="", sign=False):
95112
header = soapenv.Header()
96113
header.extension_elements = eelist
97114

98-
# ----------------------------------------
99-
# <samlp:AuthnRequest>
100-
# ----------------------------------------
101-
102-
logger.info("entityid: %s, binding: %s" % (entityid, BINDING_SOAP))
103-
104-
location = cls._sso_location(entityid, binding=BINDING_SOAP)
105-
req_id, authn_req = cls.create_authn_request(
106-
location, binding=BINDING_PAOS, service_url_binding=BINDING_PAOS)
107-
108-
body = soapenv.Body()
109-
body.extension_elements = [element_to_extension_element(authn_req)]
110-
111115
# ----------------------------------------
112116
# The SOAP envelope
113117
# ----------------------------------------
@@ -126,7 +130,7 @@ def handle_ecp_authn_response(cls, soap_message, outstanding=None):
126130
if item.c_tag == "RelayState" and item.c_namespace == ecp.NAMESPACE:
127131
_relay_state = item
128132

129-
response = authn_response(cls.config, cls.service_url(), outstanding,
133+
response = authn_response(cls.config, cls.service_urls(), outstanding,
130134
allow_unsolicited=True)
131135

132136
response.loads("%s" % rdict["body"], False, soap_message)

src/saml2/ecp_client.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def phase2(self, authn_request, rc_url, idp_entity_id, headers=None,
119119
if response.status_code != 200:
120120
raise SAMLError(
121121
"Request to IdP failed (%s): %s" % (response.status_code,
122-
response.error))
122+
response.text))
123123

124124
# SAMLP response in a SOAP envelope body, ecp response in headers
125125
respdict = self.parse_soap_message(response.text)
@@ -200,22 +200,19 @@ def ecp_conversation(self, respdict, idp_entity_id=None):
200200

201201
ht_args = self.use_soap(idp_response, args["rc_url"],
202202
[args["relay_state"]])
203-
203+
ht_args["headers"][0] = ('Content-Type', MIME_PAOS)
204204
logger.debug("[P3] Post to SP: %s", ht_args["data"])
205205

206-
ht_args["headers"].append(('Content-Type', 'application/vnd.paos+xml'))
207-
208206
# POST the package from the IdP to the SP
209-
response = self.send(args["rc_url"], "POST", **ht_args)
207+
response = self.send(**ht_args)
210208

211209
if response.status_code == 302:
212210
# ignore where the SP is redirecting us to and go for the
213211
# url I started off with.
214212
pass
215213
else:
216-
print(response.error)
217214
raise SAMLError(
218-
"Error POSTing package to SP: %s" % response.error)
215+
"Error POSTing package to SP: %s" % response.text)
219216

220217
logger.debug("[P3] SP response: %s", response.text)
221218

@@ -255,22 +252,21 @@ def operation(self, url, idp_entity_id, op, **opargs):
255252
:param opargs: Arguments to the HTTP call
256253
:return: The page
257254
"""
258-
if url not in opargs:
259-
url = self._sp
255+
sp_url = self._sp
260256

261257
# ********************************************
262258
# Phase 1 - First conversation with the SP
263259
# ********************************************
264260
# headers needed to indicate to the SP that I'm ECP enabled
265261

266262
opargs["headers"] = self.add_paos_headers(opargs["headers"])
267-
268-
response = self.send(url, op, **opargs)
269-
logger.debug("[Op] SP response: %s", response)
263+
response = self.send(sp_url, op, **opargs)
264+
logger.debug("[Op] SP response: %s" % response)
265+
print(response.text)
270266

271267
if response.status_code != 200:
272268
raise SAMLError(
273-
"Request to SP failed: %s" % response.error)
269+
"Request to SP failed: %s" % response.text)
274270

275271
# The response might be a AuthnRequest instance in a SOAP envelope
276272
# body. If so it's the start of the ECP conversation
@@ -282,19 +278,16 @@ def operation(self, url, idp_entity_id, op, **opargs):
282278
# header blocks may also be present
283279
try:
284280
respdict = self.parse_soap_message(response.text)
285-
286281
self.ecp_conversation(respdict, idp_entity_id)
287282

288283
# should by now be authenticated so this should go smoothly
289284
response = self.send(url, op, **opargs)
290285
except (soap.XmlParseError, AssertionError, KeyError):
291286
pass
292287

293-
#print("RESP",response, self.http.response)
294-
295-
if response.status_code != 404:
288+
if response.status_code >= 400:
296289
raise SAMLError("Error performing operation: %s" % (
297-
response.error,))
290+
response.text,))
298291

299292
return response
300293

src/saml2/entity.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from hashlib import sha1
99

1010
from saml2.metadata import ENDPOINTS
11-
from saml2.profile import paos, ecp
11+
from saml2.profile import paos, ecp, samlec
1212
from saml2.soap import parse_soap_enveloped_saml_artifact_resolve
1313
from saml2.soap import class_instances_from_soap_enveloped_saml_thingies
1414
from saml2.soap import open_soap_envelope
@@ -407,7 +407,8 @@ def parse_soap_message(text):
407407
"""
408408
return class_instances_from_soap_enveloped_saml_thingies(text, [paos,
409409
ecp,
410-
samlp])
410+
samlp,
411+
samlec])
411412

412413
@staticmethod
413414
def unpack_soap_message(text):

src/saml2/profile/samlec.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from saml2 import SamlBase
2+
3+
4+
NAMESPACE = 'urn:ietf:params:xml:ns:samlec'
5+
6+
7+
class GeneratedKey(SamlBase):
8+
c_tag = 'GeneratedKey'
9+
c_namespace = NAMESPACE
10+
11+
12+
ELEMENT_BY_TAG = {
13+
'GeneratedKey': GeneratedKey,
14+
}

0 commit comments

Comments
 (0)