Fixed manage_name_id request-response
Added assert_id request-response
This commit is contained in:
parent
05d514f10e
commit
85b3fc307c
@ -24,7 +24,6 @@ from saml2.mdstore import destinations
|
|||||||
from saml2.saml import AssertionIDRef
|
from saml2.saml import AssertionIDRef
|
||||||
from saml2.saml import NAMEID_FORMAT_TRANSIENT
|
from saml2.saml import NAMEID_FORMAT_TRANSIENT
|
||||||
from saml2.samlp import AuthnQuery
|
from saml2.samlp import AuthnQuery
|
||||||
from saml2.samlp import Response
|
|
||||||
from saml2.samlp import AssertionIDRequest
|
from saml2.samlp import AssertionIDRequest
|
||||||
from saml2.samlp import NameIDMappingRequest
|
from saml2.samlp import NameIDMappingRequest
|
||||||
from saml2.samlp import AttributeQuery
|
from saml2.samlp import AttributeQuery
|
||||||
@ -48,6 +47,9 @@ from saml2 import saml
|
|||||||
from saml2.population import Population
|
from saml2.population import Population
|
||||||
|
|
||||||
from saml2.response import AttributeResponse
|
from saml2.response import AttributeResponse
|
||||||
|
from saml2.response import AuthzResponse
|
||||||
|
from saml2.response import AssertionIDResponse
|
||||||
|
from saml2.response import AuthnQueryResponse
|
||||||
from saml2.response import NameIDMappingResponse
|
from saml2.response import NameIDMappingResponse
|
||||||
from saml2.response import AuthnResponse
|
from saml2.response import AuthnResponse
|
||||||
|
|
||||||
@ -491,17 +493,21 @@ class Base(Entity):
|
|||||||
""" Verify that the response is OK
|
""" Verify that the response is OK
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self._parse_response(response, Response, "", binding)
|
return self._parse_response(response, AuthzResponse, "", binding)
|
||||||
|
|
||||||
def parse_authn_query_response(self, response, binding=BINDING_SOAP):
|
def parse_authn_query_response(self, response, binding=BINDING_SOAP):
|
||||||
""" Verify that the response is OK
|
""" Verify that the response is OK
|
||||||
"""
|
"""
|
||||||
return self._parse_response(response, Response, "", binding)
|
return self._parse_response(response, AuthnQueryResponse, "", binding)
|
||||||
|
|
||||||
def parse_assertion_id_request_response(self, response, binding):
|
def parse_assertion_id_request_response(self, response, binding):
|
||||||
""" Verify that the response is OK
|
""" Verify that the response is OK
|
||||||
"""
|
"""
|
||||||
return self._parse_response(response, Response, "", binding)
|
kwargs = {"entity_id": self.config.entityid,
|
||||||
|
"attribute_converters": self.config.attribute_converters}
|
||||||
|
|
||||||
|
return self._parse_response(response, AssertionIDResponse, "", binding,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------
|
# ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -146,6 +146,7 @@ class Entity(HTTPBase):
|
|||||||
entity_id = request.issuer.text.strip()
|
entity_id = request.issuer.text.strip()
|
||||||
|
|
||||||
sfunc = getattr(self.metadata, service)
|
sfunc = getattr(self.metadata, service)
|
||||||
|
|
||||||
if bindings is None:
|
if bindings is None:
|
||||||
bindings = self.config.preferred_binding[service]
|
bindings = self.config.preferred_binding[service]
|
||||||
|
|
||||||
@ -175,8 +176,9 @@ class Entity(HTTPBase):
|
|||||||
return {"id":id, "version":VERSION,
|
return {"id":id, "version":VERSION,
|
||||||
"issue_instant":instant(), "issuer":self._issuer()}
|
"issue_instant":instant(), "issuer":self._issuer()}
|
||||||
|
|
||||||
def response_args(self, message, bindings, descr_type=""):
|
def response_args(self, message, bindings=None, descr_type=""):
|
||||||
info = {"in_response_to": message.id}
|
info = {"in_response_to": message.id}
|
||||||
|
|
||||||
if isinstance(message, AuthnRequest):
|
if isinstance(message, AuthnRequest):
|
||||||
rsrv = "assertion_consumer_service"
|
rsrv = "assertion_consumer_service"
|
||||||
descr_type = "sp_sso"
|
descr_type = "sp_sso"
|
||||||
@ -189,7 +191,9 @@ class Entity(HTTPBase):
|
|||||||
descr_type = "sp_sso"
|
descr_type = "sp_sso"
|
||||||
elif isinstance(message, ManageNameIDRequest):
|
elif isinstance(message, ManageNameIDRequest):
|
||||||
rsrv = "manage_name_id_service"
|
rsrv = "manage_name_id_service"
|
||||||
# The once below are solely SOAP
|
# The once below are solely SOAP so no return destination needed
|
||||||
|
elif isinstance(message, AssertionIDRequest):
|
||||||
|
rsrv = ""
|
||||||
elif isinstance(message, ArtifactResolve):
|
elif isinstance(message, ArtifactResolve):
|
||||||
rsrv = ""
|
rsrv = ""
|
||||||
elif isinstance(message, AssertionIDRequest):
|
elif isinstance(message, AssertionIDRequest):
|
||||||
@ -209,6 +213,7 @@ class Entity(HTTPBase):
|
|||||||
binding, destination = self.pick_binding(rsrv, bindings,
|
binding, destination = self.pick_binding(rsrv, bindings,
|
||||||
descr_type=descr_type,
|
descr_type=descr_type,
|
||||||
request=message)
|
request=message)
|
||||||
|
#info["binding"] = binding
|
||||||
info["destination"] = destination
|
info["destination"] = destination
|
||||||
|
|
||||||
return info
|
return info
|
||||||
@ -488,7 +493,8 @@ class Entity(HTTPBase):
|
|||||||
def create_manage_name_id_request(self, destination, id=0, consent=None,
|
def create_manage_name_id_request(self, destination, id=0, consent=None,
|
||||||
extensions=None, sign=False,
|
extensions=None, sign=False,
|
||||||
name_id=None, new_id=None,
|
name_id=None, new_id=None,
|
||||||
encrypted_id=None, new_encrypted_id=None):
|
encrypted_id=None, new_encrypted_id=None,
|
||||||
|
terminate=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param destination:
|
:param destination:
|
||||||
@ -500,6 +506,7 @@ class Entity(HTTPBase):
|
|||||||
:param new_id:
|
:param new_id:
|
||||||
:param encrypted_id:
|
:param encrypted_id:
|
||||||
:param new_encrypted_id:
|
:param new_encrypted_id:
|
||||||
|
:param terminate:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
kwargs = self.message_args(id)
|
kwargs = self.message_args(id)
|
||||||
@ -515,8 +522,10 @@ class Entity(HTTPBase):
|
|||||||
kwargs["new_id"] = new_id
|
kwargs["new_id"] = new_id
|
||||||
elif new_encrypted_id:
|
elif new_encrypted_id:
|
||||||
kwargs["new_encrypted_id"] = new_encrypted_id
|
kwargs["new_encrypted_id"] = new_encrypted_id
|
||||||
|
elif terminate:
|
||||||
|
kwargs["terminate"] = terminate
|
||||||
else:
|
else:
|
||||||
kwargs["terminate"] = ""
|
raise AttributeError("One of NewID, NewEncryptedNameID or Terminate has to be provided")
|
||||||
|
|
||||||
return self._message(ManageNameIDRequest, destination, consent=consent,
|
return self._message(ManageNameIDRequest, destination, consent=consent,
|
||||||
extensions=extensions, sign=sign, **kwargs)
|
extensions=extensions, sign=sign, **kwargs)
|
||||||
@ -534,13 +543,13 @@ class Entity(HTTPBase):
|
|||||||
return self._parse_request(xmlstr, request.ManageNameIDRequest,
|
return self._parse_request(xmlstr, request.ManageNameIDRequest,
|
||||||
"manage_name_id_service", binding)
|
"manage_name_id_service", binding)
|
||||||
|
|
||||||
def create_manage_name_id_response(self, request, bindings, status=None,
|
def create_manage_name_id_response(self, request, bindings=None,
|
||||||
sign=False, issuer=None):
|
status=None, sign=False, issuer=None):
|
||||||
|
|
||||||
rinfo = self.response_args(request, bindings)
|
rinfo = self.response_args(request, bindings)
|
||||||
|
|
||||||
response = self._status_response(samlp.ManageNameIDResponse, issuer,
|
response = self._status_response(samlp.ManageNameIDResponse, issuer,
|
||||||
status, sign=False, **rinfo)
|
status, sign, **rinfo)
|
||||||
|
|
||||||
logger.info("Response: %s" % (response,))
|
logger.info("Response: %s" % (response,))
|
||||||
|
|
||||||
@ -582,7 +591,7 @@ class Entity(HTTPBase):
|
|||||||
response = response_cls(self.sec, **kwargs)
|
response = response_cls(self.sec, **kwargs)
|
||||||
except Exception, exc:
|
except Exception, exc:
|
||||||
logger.info("%s" % exc)
|
logger.info("%s" % exc)
|
||||||
return None
|
raise
|
||||||
|
|
||||||
xmlstr = self.unravel(xmlstr, binding, response_cls.msgtype)
|
xmlstr = self.unravel(xmlstr, binding, response_cls.msgtype)
|
||||||
|
|
||||||
@ -698,4 +707,8 @@ class Entity(HTTPBase):
|
|||||||
# should just be one
|
# should just be one
|
||||||
elems = extension_elements_to_elements(resp.response.extension_elements,
|
elems = extension_elements_to_elements(resp.response.extension_elements,
|
||||||
[samlp, saml])
|
[samlp, saml])
|
||||||
return elems[0]
|
return elems[0]
|
||||||
|
|
||||||
|
def parse_manage_name_id_response(self, xmlstr, binding=BINDING_SOAP):
|
||||||
|
return self._parse_response(xmlstr, response.ManageNameIDResponse,
|
||||||
|
"manage_name_id_service", binding)
|
||||||
|
@ -155,7 +155,19 @@ class AuthnRequest(Request):
|
|||||||
|
|
||||||
def attributes(self):
|
def attributes(self):
|
||||||
return to_local(self.attribute_converters, self.message)
|
return to_local(self.attribute_converters, self.message)
|
||||||
|
|
||||||
|
|
||||||
|
class AssertionIDRequest(Request):
|
||||||
|
msgtype = "assertion_id_request"
|
||||||
|
def __init__(self, sec_context, receiver_addrs, attribute_converters,
|
||||||
|
timeslack=0):
|
||||||
|
Request.__init__(self, sec_context, receiver_addrs,
|
||||||
|
attribute_converters, timeslack)
|
||||||
|
self.signature_check = self.sec.correctly_signed_assertion_id_request
|
||||||
|
|
||||||
|
def attributes(self):
|
||||||
|
return to_local(self.attribute_converters, self.message)
|
||||||
|
|
||||||
|
|
||||||
class AuthzDecisionQuery(Request):
|
class AuthzDecisionQuery(Request):
|
||||||
msgtype = "authz_decision_query"
|
msgtype = "authz_decision_query"
|
||||||
|
@ -256,6 +256,16 @@ class NameIDMappingResponse(StatusResponse):
|
|||||||
request_id, asynchop)
|
request_id, asynchop)
|
||||||
self.signature_check = self.sec.correctly_signed_name_id_mapping_response
|
self.signature_check = self.sec.correctly_signed_name_id_mapping_response
|
||||||
|
|
||||||
|
class ManageNameIDResponse(StatusResponse):
|
||||||
|
msgtype = "manage_name_id_response"
|
||||||
|
|
||||||
|
def __init__(self, sec_context, return_addr=None, timeslack=0,
|
||||||
|
request_id=0, asynchop=True):
|
||||||
|
StatusResponse.__init__(self, sec_context, return_addr, timeslack,
|
||||||
|
request_id, asynchop)
|
||||||
|
self.signature_check = self.sec.correctly_signed_manage_name_id_response
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class AuthnResponse(StatusResponse):
|
class AuthnResponse(StatusResponse):
|
||||||
@ -632,6 +642,35 @@ class AuthnResponse(StatusResponse):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s" % self.xmlstr
|
return "%s" % self.xmlstr
|
||||||
|
|
||||||
|
class AssertionIDResponse(AuthnResponse):
|
||||||
|
msgtype = "assertion_id_response"
|
||||||
|
|
||||||
|
def __init__(self, sec_context, attribute_converters, entity_id,
|
||||||
|
return_addr=None, timeslack=0, asynchop=False, test=False):
|
||||||
|
|
||||||
|
AuthnResponse.__init__(self, sec_context, attribute_converters,
|
||||||
|
entity_id, return_addr, timeslack=timeslack,
|
||||||
|
asynchop=asynchop, test=test)
|
||||||
|
self.entity_id = entity_id
|
||||||
|
self.attribute_converters = attribute_converters
|
||||||
|
self.assertion = None
|
||||||
|
self.context = "AssertionIdResponse"
|
||||||
|
|
||||||
|
class AuthnQueryResponse(AuthnResponse):
|
||||||
|
msgtype = "authn_query_response"
|
||||||
|
|
||||||
|
def __init__(self, sec_context, attribute_converters, entity_id,
|
||||||
|
return_addr=None, timeslack=0, asynchop=False, test=False):
|
||||||
|
|
||||||
|
AuthnResponse.__init__(self, sec_context, attribute_converters,
|
||||||
|
entity_id, return_addr, timeslack=timeslack,
|
||||||
|
asynchop=asynchop, test=test)
|
||||||
|
self.entity_id = entity_id
|
||||||
|
self.attribute_converters = attribute_converters
|
||||||
|
self.assertion = None
|
||||||
|
self.context = "AuthnQueryResponse"
|
||||||
|
|
||||||
|
|
||||||
class AttributeResponse(AuthnResponse):
|
class AttributeResponse(AuthnResponse):
|
||||||
msgtype = "attribute_response"
|
msgtype = "attribute_response"
|
||||||
|
|
||||||
|
@ -23,9 +23,8 @@ import logging
|
|||||||
import shelve
|
import shelve
|
||||||
import sys
|
import sys
|
||||||
import memcache
|
import memcache
|
||||||
from saml2.soap import parse_soap_enveloped_saml_name_id_mapping_request
|
from saml2.samlp import AuthzDecisionQuery
|
||||||
from saml2.samlp import AuthzDecisionQuery, NameIDMappingResponse
|
from saml2.samlp import NameIDMappingResponse
|
||||||
from saml2.samlp import AssertionIDRequest
|
|
||||||
from saml2.samlp import AuthnQuery
|
from saml2.samlp import AuthnQuery
|
||||||
from saml2.entity import Entity
|
from saml2.entity import Entity
|
||||||
|
|
||||||
@ -34,6 +33,7 @@ from saml2 import class_name
|
|||||||
from saml2 import BINDING_HTTP_REDIRECT
|
from saml2 import BINDING_HTTP_REDIRECT
|
||||||
|
|
||||||
from saml2.request import AuthnRequest
|
from saml2.request import AuthnRequest
|
||||||
|
from saml2.request import AssertionIDRequest
|
||||||
from saml2.request import AttributeQuery
|
from saml2.request import AttributeQuery
|
||||||
from saml2.request import NameIDMappingRequest
|
from saml2.request import NameIDMappingRequest
|
||||||
|
|
||||||
@ -619,3 +619,4 @@ class Server(Entity):
|
|||||||
else:
|
else:
|
||||||
logger.info("Message: %s" % _resp)
|
logger.info("Message: %s" % _resp)
|
||||||
return _resp
|
return _resp
|
||||||
|
|
||||||
|
@ -822,6 +822,18 @@ class SecurityContext(object):
|
|||||||
"manage_name_id_request",
|
"manage_name_id_request",
|
||||||
must, origdoc)
|
must, origdoc)
|
||||||
|
|
||||||
|
def correctly_signed_manage_name_id_response(self, decoded_xml, must=False,
|
||||||
|
origdoc=None):
|
||||||
|
return self.correctly_signed_message(decoded_xml,
|
||||||
|
"manage_name_id_response", must,
|
||||||
|
origdoc)
|
||||||
|
|
||||||
|
def correctly_signed_assertion_id_request(self, decoded_xml, must=False,
|
||||||
|
origdoc=None):
|
||||||
|
return self.correctly_signed_message(decoded_xml,
|
||||||
|
"assertion_id_request", must,
|
||||||
|
origdoc)
|
||||||
|
|
||||||
def correctly_signed_response(self, decoded_xml, must=False, origdoc=None):
|
def correctly_signed_response(self, decoded_xml, must=False, origdoc=None):
|
||||||
""" Check if a instance is correctly signed, if we have metadata for
|
""" Check if a instance is correctly signed, if we have metadata for
|
||||||
the IdP that sent the info use that, if not use the key that are in
|
the IdP that sent the info use that, if not use the key that are in
|
||||||
|
@ -79,6 +79,19 @@ def parse_soap_enveloped_saml_manage_name_id_request(text):
|
|||||||
expected_tag = '{%s}ManageNameIDRequest' % SAMLP_NAMESPACE
|
expected_tag = '{%s}ManageNameIDRequest' % SAMLP_NAMESPACE
|
||||||
return parse_soap_enveloped_saml_thingy(text, [expected_tag])
|
return parse_soap_enveloped_saml_thingy(text, [expected_tag])
|
||||||
|
|
||||||
|
def parse_soap_enveloped_saml_manage_name_id_response(text):
|
||||||
|
expected_tag = '{%s}ManageNameIDResponse' % SAMLP_NAMESPACE
|
||||||
|
return parse_soap_enveloped_saml_thingy(text, [expected_tag])
|
||||||
|
|
||||||
|
def parse_soap_enveloped_saml_assertion_id_request(text):
|
||||||
|
expected_tag = '{%s}AssertionIDRequest' % SAMLP_NAMESPACE
|
||||||
|
return parse_soap_enveloped_saml_thingy(text, [expected_tag])
|
||||||
|
|
||||||
|
def parse_soap_enveloped_saml_assertion_id_response(text):
|
||||||
|
tags = ['{%s}Response' % SAMLP_NAMESPACE,
|
||||||
|
'{%s}AssertionIDResponse' % SAMLP_NAMESPACE]
|
||||||
|
return parse_soap_enveloped_saml_thingy(text, tags)
|
||||||
|
|
||||||
#def parse_soap_enveloped_saml_logout_response(text):
|
#def parse_soap_enveloped_saml_logout_response(text):
|
||||||
# expected_tag = '{%s}LogoutResponse' % SAMLP_NAMESPACE
|
# expected_tag = '{%s}LogoutResponse' % SAMLP_NAMESPACE
|
||||||
# return parse_soap_enveloped_saml_thingy(text, [expected_tag])
|
# return parse_soap_enveloped_saml_thingy(text, [expected_tag])
|
||||||
@ -110,8 +123,8 @@ def parse_soap_enveloped_saml_thingy(text, expected_tags):
|
|||||||
if saml_part.tag in expected_tags:
|
if saml_part.tag in expected_tags:
|
||||||
return ElementTree.tostring(saml_part, encoding="UTF-8")
|
return ElementTree.tostring(saml_part, encoding="UTF-8")
|
||||||
else:
|
else:
|
||||||
raise WrongMessageType("Was '%s' expected '%s'" % (saml_part.tag,
|
raise WrongMessageType("Was '%s' expected one of %s" % (saml_part.tag,
|
||||||
expected_tags))
|
expected_tags))
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from saml2 import BINDING_SOAP
|
||||||
from saml2.samlp import NewID
|
from saml2.samlp import NewID
|
||||||
from saml2.saml import NameID, NAMEID_FORMAT_TRANSIENT
|
from saml2.saml import NameID, NAMEID_FORMAT_TRANSIENT
|
||||||
from saml2.client import Saml2Client
|
from saml2.client import Saml2Client
|
||||||
@ -29,3 +30,45 @@ def test_basic():
|
|||||||
print _req.message
|
print _req.message
|
||||||
|
|
||||||
assert mid.id == _req.message.id
|
assert mid.id == _req.message.id
|
||||||
|
|
||||||
|
def test_flow():
|
||||||
|
sp = Saml2Client(config_file="servera_conf")
|
||||||
|
idp = Server(config_file="idp_all_conf")
|
||||||
|
|
||||||
|
binding, destination = sp.pick_binding("manage_name_id_service",
|
||||||
|
entity_id=idp.config.entityid)
|
||||||
|
|
||||||
|
nameid = NameID(format=NAMEID_FORMAT_TRANSIENT, text="foobar")
|
||||||
|
newid = NewID(text="Barfoo")
|
||||||
|
|
||||||
|
mid = sp.create_manage_name_id_request(destination, name_id=nameid,
|
||||||
|
new_id=newid)
|
||||||
|
|
||||||
|
print mid
|
||||||
|
rargs = sp.apply_binding(binding, "%s" % mid, destination, "")
|
||||||
|
|
||||||
|
# --------- @IDP --------------
|
||||||
|
|
||||||
|
_req = idp.parse_manage_name_id_request(rargs["data"], binding)
|
||||||
|
|
||||||
|
print _req.message
|
||||||
|
|
||||||
|
mnir = idp.create_manage_name_id_response(_req.message, None)
|
||||||
|
|
||||||
|
if binding != BINDING_SOAP:
|
||||||
|
binding, destination = idp.pick_binding("manage_name_id_service",
|
||||||
|
entity_id=sp.config.entityid)
|
||||||
|
else:
|
||||||
|
destination = ""
|
||||||
|
|
||||||
|
respargs = idp.apply_binding(binding, "%s" % mnir, destination, "")
|
||||||
|
|
||||||
|
print respargs
|
||||||
|
|
||||||
|
# ---------- @SP ---------------
|
||||||
|
|
||||||
|
_response = sp.parse_manage_name_id_response(respargs["data"], binding)
|
||||||
|
|
||||||
|
print _response.response
|
||||||
|
|
||||||
|
assert _response.response.id == mnir.id
|
104
tests/test_68_assertion_id.py
Normal file
104
tests/test_68_assertion_id.py
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
from urlparse import parse_qs
|
||||||
|
from urlparse import urlparse
|
||||||
|
from saml2.samlp import AuthnRequest
|
||||||
|
from saml2.samlp import NameIDPolicy
|
||||||
|
from saml2.saml import AUTHN_PASSWORD
|
||||||
|
from saml2.saml import NAMEID_FORMAT_TRANSIENT
|
||||||
|
from saml2 import BINDING_HTTP_POST
|
||||||
|
from saml2 import BINDING_SOAP
|
||||||
|
from saml2.client import Saml2Client
|
||||||
|
from saml2.server import Server
|
||||||
|
|
||||||
|
__author__ = 'rolandh'
|
||||||
|
|
||||||
|
TAG1 = "name=\"SAMLRequest\" value="
|
||||||
|
|
||||||
|
def get_msg(hinfo, binding):
|
||||||
|
if binding == BINDING_SOAP:
|
||||||
|
xmlstr = hinfo["data"]
|
||||||
|
elif binding == BINDING_HTTP_POST:
|
||||||
|
_inp = hinfo["data"][3]
|
||||||
|
i = _inp.find(TAG1)
|
||||||
|
i += len(TAG1) + 1
|
||||||
|
j = _inp.find('"', i)
|
||||||
|
xmlstr = _inp[i:j]
|
||||||
|
else: # BINDING_HTTP_REDIRECT
|
||||||
|
parts = urlparse(hinfo["headers"][0][1])
|
||||||
|
xmlstr = parse_qs(parts.query)["SAMLRequest"][0]
|
||||||
|
|
||||||
|
return xmlstr
|
||||||
|
|
||||||
|
def test_basic_flow():
|
||||||
|
sp = Saml2Client(config_file="servera_conf")
|
||||||
|
idp = Server(config_file="idp_all_conf")
|
||||||
|
|
||||||
|
# -------- @IDP -------------
|
||||||
|
|
||||||
|
relay_state = "FOO"
|
||||||
|
# -- dummy request ---
|
||||||
|
orig_req = AuthnRequest(issuer=sp._issuer(),
|
||||||
|
name_id_policy=NameIDPolicy(allow_create="true",
|
||||||
|
format=NAMEID_FORMAT_TRANSIENT))
|
||||||
|
|
||||||
|
# == Create an AuthnRequest response
|
||||||
|
|
||||||
|
name_id = idp.ident.transient_nameid(sp.config.entityid, "id12")
|
||||||
|
binding, destination = idp.pick_binding("assertion_consumer_service",
|
||||||
|
entity_id=sp.config.entityid)
|
||||||
|
resp = idp.create_authn_response({"eduPersonEntitlement": "Short stop",
|
||||||
|
"surName": "Jeter",
|
||||||
|
"givenName": "Derek",
|
||||||
|
"mail": "derek.jeter@nyy.mlb.com",
|
||||||
|
"title": "The man"},
|
||||||
|
"id-123456789",
|
||||||
|
destination,
|
||||||
|
sp.config.entityid,
|
||||||
|
name_id=name_id,
|
||||||
|
authn=(AUTHN_PASSWORD,
|
||||||
|
"http://www.example.com/login"))
|
||||||
|
|
||||||
|
hinfo = idp.apply_binding(binding, "%s" % resp, destination, relay_state)
|
||||||
|
|
||||||
|
# --------- @SP -------------
|
||||||
|
|
||||||
|
xmlstr = get_msg(hinfo, binding)
|
||||||
|
|
||||||
|
aresp = sp.parse_authn_request_response(xmlstr, binding,
|
||||||
|
{resp.in_response_to :"/"})
|
||||||
|
|
||||||
|
# == Look for assertion X
|
||||||
|
|
||||||
|
asid = aresp.assertion.id
|
||||||
|
|
||||||
|
binding, destination = sp.pick_binding("assertion_id_request_service",
|
||||||
|
entity_id=idp.config.entityid)
|
||||||
|
|
||||||
|
_req = sp.create_assertion_id_request([asid], destination)
|
||||||
|
|
||||||
|
hinfo = sp.apply_binding(binding, "%s" % _req, destination,
|
||||||
|
"realy_stat")
|
||||||
|
|
||||||
|
# ---------- @IDP ------------
|
||||||
|
|
||||||
|
xmlstr = get_msg(hinfo, binding)
|
||||||
|
|
||||||
|
rr = idp.parse_assertion_id_request(xmlstr, binding)
|
||||||
|
|
||||||
|
print rr
|
||||||
|
|
||||||
|
# == construct response
|
||||||
|
|
||||||
|
aids = [x.text for x in rr.message.assertion_id_ref]
|
||||||
|
resp_args = idp.response_args(rr.message)
|
||||||
|
|
||||||
|
resp = idp.create_assertion_id_request_response(aids, **resp_args)
|
||||||
|
|
||||||
|
hinfo = idp.apply_binding(binding, "%s" % resp, None, "", "SAMLResponse")
|
||||||
|
|
||||||
|
# ----------- @SP -------------
|
||||||
|
|
||||||
|
xmlstr = get_msg(hinfo, binding)
|
||||||
|
|
||||||
|
final = sp.parse_assertion_id_request_response(xmlstr, binding)
|
||||||
|
|
||||||
|
print final
|
Loading…
Reference in New Issue
Block a user