providers/saml: fix error when using post bindings and user freshly logged in
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> #1873
This commit is contained in:
parent
f0d7edb963
commit
4f54ce6afb
|
@ -53,6 +53,7 @@ NEXT_ARG_NAME = "next"
|
||||||
SESSION_KEY_PLAN = "authentik_flows_plan"
|
SESSION_KEY_PLAN = "authentik_flows_plan"
|
||||||
SESSION_KEY_APPLICATION_PRE = "authentik_flows_application_pre"
|
SESSION_KEY_APPLICATION_PRE = "authentik_flows_application_pre"
|
||||||
SESSION_KEY_GET = "authentik_flows_get"
|
SESSION_KEY_GET = "authentik_flows_get"
|
||||||
|
SESSION_KEY_POST = "authentik_flows_post"
|
||||||
SESSION_KEY_HISTORY = "authentik_flows_history"
|
SESSION_KEY_HISTORY = "authentik_flows_history"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.views.generic.base import View
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.core.models import Application, Provider, User
|
from authentik.core.models import Application, Provider, User
|
||||||
from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE
|
from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE, SESSION_KEY_POST
|
||||||
from authentik.lib.sentry import SentryIgnoredException
|
from authentik.lib.sentry import SentryIgnoredException
|
||||||
from authentik.policies.denied import AccessDeniedResponse
|
from authentik.policies.denied import AccessDeniedResponse
|
||||||
from authentik.policies.engine import PolicyEngine
|
from authentik.policies.engine import PolicyEngine
|
||||||
|
@ -84,6 +84,10 @@ class PolicyAccessView(AccessMixin, View):
|
||||||
a hint on the Identification Stage what the user should login for."""
|
a hint on the Identification Stage what the user should login for."""
|
||||||
if self.application:
|
if self.application:
|
||||||
self.request.session[SESSION_KEY_APPLICATION_PRE] = self.application
|
self.request.session[SESSION_KEY_APPLICATION_PRE] = self.application
|
||||||
|
# Because this view might get hit with a POST request, we need to preserve that data
|
||||||
|
# since later views might need it (mostly SAML)
|
||||||
|
if self.request.method.lower() == "post":
|
||||||
|
self.request.session[SESSION_KEY_POST] = self.request.POST
|
||||||
return redirect_to_login(
|
return redirect_to_login(
|
||||||
self.request.get_full_path(),
|
self.request.get_full_path(),
|
||||||
self.get_login_url(),
|
self.get_login_url(),
|
||||||
|
|
|
@ -13,7 +13,7 @@ from authentik.core.models import Application
|
||||||
from authentik.events.models import Event, EventAction
|
from authentik.events.models import Event, EventAction
|
||||||
from authentik.flows.models import in_memory_stage
|
from authentik.flows.models import in_memory_stage
|
||||||
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_SSO, FlowPlanner
|
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_SSO, FlowPlanner
|
||||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
from authentik.flows.views.executor import SESSION_KEY_PLAN, SESSION_KEY_POST
|
||||||
from authentik.lib.utils.urls import redirect_with_qs
|
from authentik.lib.utils.urls import redirect_with_qs
|
||||||
from authentik.lib.views import bad_request_message
|
from authentik.lib.views import bad_request_message
|
||||||
from authentik.policies.views import PolicyAccessView
|
from authentik.policies.views import PolicyAccessView
|
||||||
|
@ -37,7 +37,7 @@ LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
class SAMLSSOView(PolicyAccessView):
|
class SAMLSSOView(PolicyAccessView):
|
||||||
""" "SAML SSO Base View, which plans a flow and injects our final stage.
|
"""SAML SSO Base View, which plans a flow and injects our final stage.
|
||||||
Calls get/post handler."""
|
Calls get/post handler."""
|
||||||
|
|
||||||
def resolve_provider_application(self):
|
def resolve_provider_application(self):
|
||||||
|
@ -120,14 +120,20 @@ class SAMLSSOBindingPOSTView(SAMLSSOView):
|
||||||
|
|
||||||
def check_saml_request(self) -> Optional[HttpRequest]:
|
def check_saml_request(self) -> Optional[HttpRequest]:
|
||||||
"""Handle POST bindings"""
|
"""Handle POST bindings"""
|
||||||
if REQUEST_KEY_SAML_REQUEST not in self.request.POST:
|
payload = self.request.POST
|
||||||
|
# Restore the post body from the session
|
||||||
|
# This happens when using POST bindings but the user isn't logged in
|
||||||
|
# (user gets redirected and POST body is 'lost')
|
||||||
|
if SESSION_KEY_POST in self.request.session:
|
||||||
|
payload = self.request.session[SESSION_KEY_POST]
|
||||||
|
if REQUEST_KEY_SAML_REQUEST not in payload:
|
||||||
LOGGER.info("check_saml_request: SAML payload missing")
|
LOGGER.info("check_saml_request: SAML payload missing")
|
||||||
return bad_request_message(self.request, "The SAML request payload is missing.")
|
return bad_request_message(self.request, "The SAML request payload is missing.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
auth_n_request = AuthNRequestParser(self.provider).parse(
|
auth_n_request = AuthNRequestParser(self.provider).parse(
|
||||||
self.request.POST[REQUEST_KEY_SAML_REQUEST],
|
payload[REQUEST_KEY_SAML_REQUEST],
|
||||||
self.request.POST.get(REQUEST_KEY_RELAY_STATE),
|
payload.get(REQUEST_KEY_RELAY_STATE),
|
||||||
)
|
)
|
||||||
self.request.session[SESSION_KEY_AUTH_N_REQUEST] = auth_n_request
|
self.request.session[SESSION_KEY_AUTH_N_REQUEST] = auth_n_request
|
||||||
except CannotHandleAssertion as exc:
|
except CannotHandleAssertion as exc:
|
||||||
|
|
Reference in a new issue