@@ -62,31 +62,31 @@ def setup_class(self):
6262 self .conf = config_factory ("sp" , dotname ("server_conf" ))
6363 self .conf .only_use_keys_in_metadata = False
6464 self .ar = authn_response (self .conf , "http://lingon.catalogix.se:8087/" )
65-
65+
6666 def test_verify_1 (self ):
6767 xml_response = "%s" % (self ._resp_ ,)
6868 print (xml_response )
6969 self .ar .outstanding_queries = {"id12" : "http://localhost:8088/sso" }
7070 self .ar .timeslack = 10000
7171 self .ar .loads (xml_response , decode = False )
7272 self .ar .verify ()
73-
73+
7474 print (self .ar .__dict__ )
7575 assert self .ar .came_from == 'http://localhost:8088/sso'
7676 assert self .ar .session_id () == "id12"
7777 assert self .ar .ava ["givenName" ] == IDENTITY ["givenName" ]
7878 assert self .ar .name_id
7979 assert self .ar .issuer () == 'urn:mace:example.com:saml:roland:idp'
80-
80+
8181 def test_verify_signed_1 (self ):
8282 xml_response = self ._sign_resp_
8383 print (xml_response )
84-
84+
8585 self .ar .outstanding_queries = {"id12" : "http://localhost:8088/sso" }
8686 self .ar .timeslack = 10000
8787 self .ar .loads (xml_response , decode = False )
8888 self .ar .verify ()
89-
89+
9090 print (self .ar .__dict__ )
9191 assert self .ar .came_from == 'http://localhost:8088/sso'
9292 assert self .ar .session_id () == "id12"
@@ -98,14 +98,14 @@ def test_parse_2(self):
9898 with open (XML_RESPONSE_FILE ) as fp :
9999 xml_response = fp .read ()
100100 ID = "bahigehogffohiphlfmplepdpcohkhhmheppcdie"
101- self .ar .outstanding_queries = {ID : "http://localhost:8088/foo" }
101+ self .ar .outstanding_queries = {ID : "http://localhost:8088/foo" }
102102 self .ar .return_addr = "http://xenosmilus.umdc.umu.se:8087/login"
103103 self .ar .entity_id = "xenosmilus.umdc.umu.se"
104104 # roughly a year, should create the response on the fly
105105 self .ar .timeslack = 315360000 # indecent long time
106106 self .ar .loads (xml_response , decode = False )
107107 self .ar .verify ()
108-
108+
109109 print (self .ar .__dict__ )
110110 assert self .ar .came_from == 'http://localhost:8088/foo'
111111 assert self .ar .session_id () == ID
@@ -189,8 +189,78 @@ def test_unpack_nested_eptid(self):
189189 resp .loads (authn_response_xml , False )
190190 resp .parse_assertion ()
191191 ava = resp .get_identity ()
192+ assert len (ava ) == 1
192193 assert ava ["eduPersonTargetedID" ] == ["b8e734571d9adb0e6444a5b49a22f4206df24d88" ]
193194
195+ def test_multiple_attribute_statement (self ):
196+ authn_response_xml = """<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
197+ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
198+ ID="CORTO54673f841c5297dd3614527d38e217332f9e3000"
199+ Version="2.0"
200+ IssueInstant="2016-09-23T14:00:45Z"
201+ Destination="https://sp.example.com/acs/post"
202+ InResponseTo="id-Wnv7CMQO1pFJoRWgi"
203+ >
204+ <saml:Issuer>https://idp.example.com</saml:Issuer>
205+ <samlp:Status>
206+ <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
207+ </samlp:Status>
208+ <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
209+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
210+ ID="CORTOadad7cb5e1237cf30fa7ab49544c15eec582854e"
211+ Version="2.0"
212+ IssueInstant="2016-09-23T14:00:45Z"
213+ >
214+ <saml:Issuer>https://idp.example.com</saml:Issuer>
215+ <saml:Subject>
216+ <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">b8e734571d9adb0e6444a5b49a22f4206df24d88</saml:NameID>
217+ <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
218+ <saml:SubjectConfirmationData Recipient="https://sp.example.com/acs/post"
219+ InResponseTo="id-Wnv7CMQO1pFJoRWgi"
220+ />
221+ </saml:SubjectConfirmation>
222+ </saml:Subject>
223+ <saml:Conditions NotBefore="2016-09-23T14:00:44Z">
224+ <saml:AudienceRestriction>
225+ <saml:Audience>https://sp.example.com</saml:Audience>
226+ </saml:AudienceRestriction>
227+ </saml:Conditions>
228+ <saml:AuthnStatement AuthnInstant="2016-09-23T13:55:40Z"
229+ SessionIndex="_9f1148918f12525c6cad9aea29bc557afab2cb8c33"
230+ >
231+ <saml:AuthnContext>
232+ <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
233+ <saml:AuthenticatingAuthority>https://idp.example.com</saml:AuthenticatingAuthority>
234+ </saml:AuthnContext>
235+ </saml:AuthnStatement>
236+ <saml:AttributeStatement>
237+ <saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10"
238+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
239+ >
240+ <saml:AttributeValue>
241+ <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">b8e734571d9adb0e6444a5b49a22f4206df24d88</saml:NameID>
242+ </saml:AttributeValue>
243+ </saml:Attribute>
244+ </saml:AttributeStatement>
245+ <saml:AttributeStatement>
246+ <saml:Attribute Name="name"
247+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
248+ >
249+ <saml:AttributeValue xsi:type="xs:string">John Doe</saml:AttributeValue>
250+ </saml:Attribute>
251+ </saml:AttributeStatement>
252+ </saml:Assertion>
253+ </samlp:Response>"""
254+
255+ resp = authn_response (self .conf , "https://sp.example.com/acs/post" , asynchop = False , allow_unsolicited = True )
256+ resp .loads (authn_response_xml , False )
257+ resp .parse_assertion ()
258+ ava = resp .get_identity ()
259+ assert len (ava ) == 2
260+ assert ava ["eduPersonTargetedID" ] == ["b8e734571d9adb0e6444a5b49a22f4206df24d88" ]
261+ assert ava ["name" ] == ["John Doe" ]
262+
263+
194264if __name__ == "__main__" :
195265 t = TestAuthnResponse ()
196266 t .setup_class ()
0 commit comments