Skip to content

Commit 01e0faf

Browse files
author
Roland Hedberg
committed
Merge pull request #302 from rebeckag/sp2_fix
Show AuthnStatement together with all attributes on result page.
2 parents 62d12bd + ecaee0a commit 01e0faf

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

example/sp-wsgi/sp.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from __future__ import print_function
33

44
import argparse
5+
import cgi
56
import importlib
67
import logging
78
import os
89
import re
910
import sys
11+
import xml.dom.minidom
1012

1113
import six
1214
from six.moves.http_cookies import SimpleCookie
@@ -46,7 +48,7 @@
4648
logger = logging.getLogger("")
4749
hdlr = logging.FileHandler('spx.log')
4850
base_formatter = logging.Formatter(
49-
"%(asctime)s %(name)s:%(levelname)s %(message)s")
51+
"%(asctime)s %(name)s:%(levelname)s %(message)s")
5052

5153
hdlr.setFormatter(base_formatter)
5254
logger.addHandler(hdlr)
@@ -329,9 +331,15 @@ def not_authn(self):
329331

330332

331333
class User(object):
332-
def __init__(self, name_id, data):
334+
def __init__(self, name_id, data, saml_response):
333335
self.name_id = name_id
334336
self.data = data
337+
self.response = saml_response
338+
339+
@property
340+
def authn_statement(self):
341+
xml_doc = xml.dom.minidom.parseString(str(self.response.assertion.authn_statement[0]))
342+
return xml_doc.toprettyxml()
335343

336344

337345
class ACS(Service):
@@ -356,7 +364,7 @@ def do(self, response, binding, relay_state="", mtype="response"):
356364

357365
try:
358366
self.response = self.sp.parse_authn_request_response(
359-
response, binding, self.outstanding_queries, self.cache.outstanding_certs)
367+
response, binding, self.outstanding_queries, self.cache.outstanding_certs)
360368
except UnknownPrincipal as excp:
361369
logger.error("UnknownPrincipal: %s", excp)
362370
resp = ServiceError("UnknownPrincipal: %s" % (excp,))
@@ -374,7 +382,7 @@ def do(self, response, binding, relay_state="", mtype="response"):
374382

375383
logger.info("AVA: %s", self.response.ava)
376384

377-
user = User(self.response.name_id, self.response.ava)
385+
user = User(self.response.name_id, self.response.ava, self.response)
378386
cookie = self.cache.set_cookie(user)
379387

380388
resp = Redirect("/", headers=[
@@ -385,7 +393,7 @@ def do(self, response, binding, relay_state="", mtype="response"):
385393
def verify_attributes(self, ava):
386394
logger.info("SP: %s", self.sp.config.entityid)
387395
rest = POLICY.get_entity_categories(
388-
self.sp.config.entityid, self.sp.metadata)
396+
self.sp.config.entityid, self.sp.metadata)
389397

390398
akeys = [k.lower() for k in ava.keys()]
391399

@@ -470,7 +478,7 @@ def _pick_idp(self, came_from):
470478
_rstate = rndstr()
471479
self.cache.relay_state[_rstate] = geturl(self.environ)
472480
_entityid = _cli.config.ecp_endpoint(
473-
self.environ["REMOTE_ADDR"])
481+
self.environ["REMOTE_ADDR"])
474482

475483
if not _entityid:
476484
return -1, ServiceError("No IdP to talk to")
@@ -522,7 +530,7 @@ def _pick_idp(self, came_from):
522530
elif self.discosrv:
523531
if query:
524532
idp_entity_id = _cli.parse_discovery_service_response(
525-
query=self.environ.get("QUERY_STRING"))
533+
query=self.environ.get("QUERY_STRING"))
526534
if not idp_entity_id:
527535
sid_ = sid()
528536
self.cache.outstanding_queries[sid_] = came_from
@@ -532,7 +540,7 @@ def _pick_idp(self, came_from):
532540
"sp")["discovery_response"][0][0]
533541
ret += "?sid=%s" % sid_
534542
loc = _cli.create_discovery_service_request(
535-
self.discosrv, eid, **{"return": ret})
543+
self.discosrv, eid, **{"return": ret})
536544
return -1, SeeOther(loc)
537545
elif len(idps) == 1:
538546
# idps is a dictionary
@@ -549,8 +557,8 @@ def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
549557
try:
550558
# Picks a binding to use for sending the Request to the IDP
551559
_binding, destination = _cli.pick_binding(
552-
"single_sign_on_service", self.bindings, "idpsso",
553-
entity_id=entity_id)
560+
"single_sign_on_service", self.bindings, "idpsso",
561+
entity_id=entity_id)
554562
logger.debug("binding: %s, destination: %s", _binding,
555563
destination)
556564
# Binding here is the response binding that is which binding the
@@ -569,7 +577,7 @@ def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
569577
"key": req_key_str
570578
}
571579
spcertenc = SPCertEnc(x509_data=ds.X509Data(
572-
x509_certificate=ds.X509Certificate(text=cert_str)))
580+
x509_certificate=ds.X509Certificate(text=cert_str)))
573581
extensions = Extensions(extension_elements=[
574582
element_to_extension_element(spcertenc)])
575583

@@ -590,7 +598,7 @@ def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
590598
except Exception as exc:
591599
logger.exception(exc)
592600
resp = ServiceError(
593-
"Failed to construct the AuthnRequest: %s" % exc)
601+
"Failed to construct the AuthnRequest: %s" % exc)
594602
return resp
595603

596604
# remember the request
@@ -668,7 +676,9 @@ def main(environ, start_response, sp):
668676
return sso.do()
669677

670678
body = dict_to_table(user.data)
671-
body += '<br><a href="/logout">logout</a>'
679+
authn_stmt = cgi.escape(user.authn_statement)
680+
body.append('<br><pre>' + authn_stmt + "</pre>")
681+
body.append('<br><a href="/logout">logout</a>')
672682

673683
resp = Response(body)
674684
return resp(environ, start_response)

0 commit comments

Comments
 (0)