sources/saml: fix SAMLRequest not being encoded properly for Redirect bindings

This commit is contained in:
Jens Langhammer 2020-06-24 13:12:34 +02:00
parent db6cb5ad51
commit c0d8aa2303
3 changed files with 10 additions and 8 deletions

View File

@ -20,5 +20,5 @@ def deflate_and_base64_encode(inflated: bytes, encoding="utf-8"):
def nice64(src): def nice64(src):
""" Returns src base64-encoded and formatted nicely for our XML. """ """Returns src base64-encoded and formatted nicely for our XML. """
return base64.b64encode(src).decode("utf-8").replace("\n", "") return base64.b64encode(src).decode("utf-8").replace("\n", "")

View File

@ -14,7 +14,7 @@
<form method="POST" action="{{ request_url }}"> <form method="POST" action="{{ request_url }}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="SAMLRequest" value="{{ request }}" /> <input type="hidden" name="SAMLRequest" value="{{ request }}" />
<input type="hidden" name="RelayState" value="{{ token }}" /> <input type="hidden" name="RelayState" value="{{ relay_state }}" />
<div class="login-group"> <div class="login-group">
<h3> <h3>
{% blocktrans with remote=source.name %} {% blocktrans with remote=source.name %}

View File

@ -11,7 +11,7 @@ from signxml.util import strip_pem_header
from passbook.lib.views import bad_request_message from passbook.lib.views import bad_request_message
from passbook.providers.saml.utils import get_random_id, render_xml from passbook.providers.saml.utils import get_random_id, render_xml
from passbook.providers.saml.utils.encoding import nice64 from passbook.providers.saml.utils.encoding import deflate_and_base64_encode, nice64
from passbook.providers.saml.utils.time import get_time_string from passbook.providers.saml.utils.time import get_time_string
from passbook.sources.saml.exceptions import ( from passbook.sources.saml.exceptions import (
MissingSAMLResponse, MissingSAMLResponse,
@ -31,8 +31,8 @@ class InitiateView(View):
source: SAMLSource = get_object_or_404(SAMLSource, slug=source_slug) source: SAMLSource = get_object_or_404(SAMLSource, slug=source_slug)
if not source.enabled: if not source.enabled:
raise Http404 raise Http404
sso_destination = request.GET.get("next", None) relay_state = request.GET.get("next", None)
request.session["sso_destination"] = sso_destination request.session["sso_destination"] = relay_state
parameters = { parameters = {
"ACS_URL": build_full_url("acs", request, source), "ACS_URL": build_full_url("acs", request, source),
"DESTINATION": source.idp_url, "DESTINATION": source.idp_url,
@ -41,17 +41,19 @@ class InitiateView(View):
"ISSUER": get_issuer(request, source), "ISSUER": get_issuer(request, source),
} }
authn_req = get_authnrequest_xml(parameters, signed=False) authn_req = get_authnrequest_xml(parameters, signed=False)
_request = nice64(str.encode(authn_req))
if source.binding_type == SAMLBindingTypes.Redirect: if source.binding_type == SAMLBindingTypes.Redirect:
return redirect(source.idp_url + "?" + urlencode({"SAMLRequest": _request})) _request = deflate_and_base64_encode(authn_req.encode())
url_args = urlencode({"SAMLRequest": _request, "RelayState": relay_state})
return redirect(f"{source.idp_url}?{url_args}")
if source.binding_type == SAMLBindingTypes.POST: if source.binding_type == SAMLBindingTypes.POST:
_request = nice64(authn_req.encode())
return render( return render(
request, request,
"saml/sp/login.html", "saml/sp/login.html",
{ {
"request_url": source.idp_url, "request_url": source.idp_url,
"request": _request, "request": _request,
"token": sso_destination, "relay_state": relay_state,
"source": source, "source": source,
}, },
) )