22from __future__ import print_function
33
44import argparse
5+ import cgi
56import importlib
67import logging
78import os
89import re
910import sys
11+ import xml .dom .minidom
1012
1113import six
1214from six .moves .http_cookies import SimpleCookie
4648logger = logging .getLogger ("" )
4749hdlr = logging .FileHandler ('spx.log' )
4850base_formatter = logging .Formatter (
49- "%(asctime)s %(name)s:%(levelname)s %(message)s" )
51+ "%(asctime)s %(name)s:%(levelname)s %(message)s" )
5052
5153hdlr .setFormatter (base_formatter )
5254logger .addHandler (hdlr )
@@ -329,9 +331,15 @@ def not_authn(self):
329331
330332
331333class 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
337345class 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