Skip to content

Commit f671747

Browse files
Merge pull request #577 from johanlundberg/non_standard_status_code
Handle non standard response error status codes
2 parents 65b136e + 19b21e2 commit f671747

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

src/saml2/response.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -354,26 +354,29 @@ def _loads(self, xmldata, decode=True, origxml=None):
354354
return self._postamble()
355355

356356
def status_ok(self):
357-
if self.response.status:
358-
status = self.response.status
359-
logger.info("status: %s", status)
360-
if status.status_code.value != samlp.STATUS_SUCCESS:
361-
logger.info("Not successful operation: %s", status)
362-
if status.status_code.status_code:
363-
excep = STATUSCODE2EXCEPTION[
364-
status.status_code.status_code.value]
365-
else:
366-
excep = StatusError
367-
if status.status_message:
368-
msg = status.status_message.text
369-
else:
370-
try:
371-
msg = status.status_code.status_code.value
372-
except Exception:
373-
msg = "Unknown error"
374-
raise excep(
375-
"%s from %s" % (msg, status.status_code.value,))
376-
return True
357+
status = self.response.status
358+
logger.info("status: %s", status)
359+
360+
if not status or status.status_code.value == samlp.STATUS_SUCCESS:
361+
return True
362+
363+
err_code = (
364+
status.status_code.status_code.value
365+
if status.status_code.status_code
366+
else None
367+
)
368+
err_msg = (
369+
status.status_message.text
370+
if status.status_message
371+
else err_code or "Unknown error"
372+
)
373+
err_cls = STATUSCODE2EXCEPTION.get(err_code, StatusError)
374+
375+
msg = "Unsuccessful operation: {status}\n{msg} from {code}".format(
376+
status=status, msg=err_msg, code=err_code
377+
)
378+
logger.info(msg)
379+
raise err_cls(msg)
377380

378381
def issue_instant_ok(self):
379382
""" Check that the response was issued at a reasonable time """

tests/test_51_client.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from saml2.authn_context import INTERNETPROTOCOLPASSWORD
2929
from saml2.client import Saml2Client
3030
from saml2.pack import parse_soap_enveloped_saml
31-
from saml2.response import LogoutResponse, StatusInvalidNameidPolicy
31+
from saml2.response import LogoutResponse, StatusInvalidNameidPolicy, StatusError
3232
from saml2.saml import NAMEID_FORMAT_PERSISTENT, EncryptedAssertion, Advice
3333
from saml2.saml import NAMEID_FORMAT_TRANSIENT
3434
from saml2.saml import NameID
@@ -2325,6 +2325,37 @@ def test_response_error_status(self):
23252325
resp_str, BINDING_HTTP_POST,
23262326
{"id1": "http://foo.example.com/service"})
23272327

2328+
def test_response_error_status_non_standard_status_code(self):
2329+
""" Test that the SP client can parse an authentication response
2330+
from an IdP that contains an error status."""
2331+
2332+
conf = config.SPConfig()
2333+
conf.load_file("server_conf")
2334+
client = Saml2Client(conf)
2335+
2336+
resp = self.server.create_error_response(
2337+
in_response_to="id1",
2338+
destination="http://lingon.catalogix.se:8087/",
2339+
info=('http://example.com/status/1.0/cancel', None),
2340+
)
2341+
2342+
# Cast the response to a string and encode it to mock up the payload
2343+
# the SP client is expected to receive via HTTP POST binding.
2344+
if six.PY2:
2345+
resp_str = encode_fn(str(resp))
2346+
else:
2347+
resp_str = encode_fn(bytes(str(resp), 'utf-8'))
2348+
2349+
# We do not need the client to verify a signature for this test.
2350+
client.want_assertions_signed = False
2351+
client.want_response_signed = False
2352+
2353+
# Parse the authentication error response
2354+
with raises(StatusError):
2355+
client.parse_authn_request_response(
2356+
resp_str, BINDING_HTTP_POST,
2357+
{"id1": "http://foo.example.com/service"})
2358+
23282359
def setup_verify_authn_response(self):
23292360
idp = "urn:mace:example.com:saml:roland:idp"
23302361
ava = {"givenName": ["Dave"], "sn": ["Concepción"],

0 commit comments

Comments
 (0)