Skip to content

Commit

Permalink
Improve support for SigAlg usage in HTTP redirect.
Browse files Browse the repository at this point in the history
  • Loading branch information
Roland Hedberg committed Jun 27, 2015
1 parent b7f618b commit ed1bb33
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 36 deletions.
8 changes: 5 additions & 3 deletions example/sp-wsgi/sp.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ def _pick_idp(self, came_from):
logger.info("Chosen IdP: '%s'" % idp_entity_id)
return 0, idp_entity_id

def redirect_to_auth(self, _cli, entity_id, came_from):
def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
try:
# Picks a binding to use for sending the Request to the IDP
_binding, destination = _cli.pick_binding(
Expand Down Expand Up @@ -573,11 +573,13 @@ def redirect_to_auth(self, _cli, entity_id, came_from):
element_to_extension_element(spcertenc)])

req_id, req = _cli.create_authn_request(destination,
binding=return_binding, extensions=extensions)
binding=return_binding,
extensions=extensions)
_rstate = rndstr()
self.cache.relay_state[_rstate] = came_from
ht_args = _cli.apply_binding(_binding, "%s" % req, destination,
relay_state=_rstate)
relay_state=_rstate,
sigalg=sigalg)
_sid = req_id

if cert is not None:
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ def run_tests(self):
"Development Status :: 4 - Beta",
"License :: OSI Approved :: Apache Software License",
"Topic :: Software Development :: Libraries :: Python Modules",
"Programming Language :: Python :: 2.7"],
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.4"
],

scripts=["tools/parse_xsd2.py", "tools/make_metadata.py",
"tools/mdexport.py", "tools/merge_metadata.py"],
Expand Down
54 changes: 28 additions & 26 deletions src/saml2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
from saml2.time_util import not_on_or_after
from saml2.saml import AssertionIDRef
from saml2.client_base import Base
from saml2.client_base import SignOnError
from saml2.client_base import LogoutError
from saml2.client_base import NoServiceDefined
from saml2.mdstore import destinations

try:
from urlparse import parse_qs
from urllib.parse import parse_qs
except ImportError:
# Compatibility with Python <= 2.5
from cgi import parse_qs
from urlparse import parse_qs

import logging

Expand All @@ -42,13 +42,11 @@
class Saml2Client(Base):
""" The basic pySAML2 service provider class """

def prepare_for_authenticate(self, entityid=None, relay_state="",
binding=saml2.BINDING_HTTP_REDIRECT, vorg="",
nameid_format=None,
scoping=None, consent=None, extensions=None,
sign=None,
response_binding=saml2.BINDING_HTTP_POST,
**kwargs):
def prepare_for_authenticate(
self, entityid=None, relay_state="",
binding=saml2.BINDING_HTTP_REDIRECT, vorg="", nameid_format=None,
scoping=None, consent=None, extensions=None, sign=None,
response_binding=saml2.BINDING_HTTP_POST, **kwargs):
""" Makes all necessary preparations for an authentication request.
:param entityid: The entity ID of the IdP to send the request to
Expand Down Expand Up @@ -82,14 +80,12 @@ def prepare_for_authenticate(self, entityid=None, relay_state="",

return reqid, info

def prepare_for_negotiated_authenticate(self, entityid=None, relay_state="",
binding=None, vorg="",
nameid_format=None,
scoping=None, consent=None, extensions=None,
sign=None,
response_binding=saml2.BINDING_HTTP_POST,
**kwargs):
""" Makes all necessary preparations for an authentication request that negotiates
def prepare_for_negotiated_authenticate(
self, entityid=None, relay_state="", binding=None, vorg="",
nameid_format=None, scoping=None, consent=None, extensions=None,
sign=None, response_binding=saml2.BINDING_HTTP_POST, **kwargs):
""" Makes all necessary preparations for an authentication request
that negotiates
which binding to use for authentication.
:param entityid: The entity ID of the IdP to send the request to
Expand Down Expand Up @@ -117,20 +113,25 @@ def prepare_for_negotiated_authenticate(self, entityid=None, relay_state="",

reqid, request = self.create_authn_request(
destination, vorg, scoping, response_binding, nameid_format,
consent=consent,
extensions=extensions, sign=sign,
consent=consent, extensions=extensions, sign=sign,
**kwargs)

_req_str = str(request)

logger.info("AuthNReq: %s" % _req_str)

try:
sigalg = kwargs["sigalg"]
except KeyError:
sigalg = ""

http_info = self.apply_binding(binding, _req_str, destination,
relay_state)
relay_state, sigalg=sigalg)

return reqid, binding, http_info
else:
raise SignOnError("No supported bindings available for authentication")
raise SignOnError(
"No supported bindings available for authentication")

def global_logout(self, name_id, reason="", expire=None, sign=None):
""" More or less a layer of indirection :-/
Expand Down Expand Up @@ -206,7 +207,7 @@ def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
destination, entity_id, name_id=name_id, reason=reason,
expire=expire)

#to_sign = []
# to_sign = []
if binding.startswith("http://"):
sign = True

Expand All @@ -230,7 +231,8 @@ def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
not_done.remove(entity_id)
response = response.text
logger.info("Response: %s" % response)
res = self.parse_logout_request_response(response, binding)
res = self.parse_logout_request_response(response,
binding)
responses[entity_id] = res
else:
logger.info("NOT OK response from %s" % destination)
Expand Down Expand Up @@ -324,15 +326,15 @@ def _use_soap(self, destination, query_type, **kwargs):
raise HTTPError("%d:%s" % (response.status_code, response.error))

if response:
#not_done.remove(entity_id)
# not_done.remove(entity_id)
logger.info("OK response from %s" % destination)
return response
else:
logger.info("NOT OK response from %s" % destination)

return None

#noinspection PyUnusedLocal
# noinspection PyUnusedLocal
def do_authz_decision_query(self, entity_id, action,
subject_id, nameid_format,
evidence=None, resource=None,
Expand Down
4 changes: 2 additions & 2 deletions src/saml2/httpbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from six.moves import http_cookiejar
import copy
import re
import urllib
from six.moves.urllib.parse import urlparse
from six.moves.urllib.parse import urlencode
import requests
Expand Down Expand Up @@ -311,7 +310,8 @@ def use_http_uri(message, typ, destination="", relay_state=""):

return info

def use_soap(self, request, destination="", soap_headers=None, sign=False):
def use_soap(self, request, destination="", soap_headers=None, sign=False,
**kwargs):
"""
Construct the necessary information for using SOAP+POST
Expand Down
9 changes: 5 additions & 4 deletions src/saml2/pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@


def http_form_post_message(message, location, relay_state="",
typ="SAMLRequest"):
typ="SAMLRequest", **kwargs):
"""The HTTP POST binding defines a mechanism by which SAML protocol
messages may be transmitted within the base64-encoded content of a
HTML form control.
Expand Down Expand Up @@ -80,7 +80,7 @@ def http_form_post_message(message, location, relay_state="",


def http_redirect_message(message, location, relay_state="", typ="SAMLRequest",
sigalg=None, key=None):
sigalg=None, key=None, **kwargs):
"""The HTTP Redirect binding defines a mechanism by which SAML protocol
messages can be transmitted within URL parameters.
Messages are encoded for use with this binding using a URL encoding
Expand Down Expand Up @@ -256,5 +256,6 @@ def packager(identifier):
raise Exception("Unknown binding type: %s" % identifier)


def factory(binding, message, location, relay_state="", typ="SAMLRequest"):
return PACKING[binding](message, location, relay_state, typ)
def factory(binding, message, location, relay_state="", typ="SAMLRequest",
**kwargs):
return PACKING[binding](message, location, relay_state, typ, **kwargs)

0 comments on commit ed1bb33

Please sign in to comment.