コード例 #1
0
ファイル: views.py プロジェクト: whit-colm/authentik
 def get(self, request: HttpRequest, source_slug: str) -> HttpResponse:
     """Replies with an XHTML SSO Request."""
     source: SAMLSource = get_object_or_404(SAMLSource, slug=source_slug)
     if not source.enabled:
         raise Http404
     relay_state = request.GET.get("next", "")
     auth_n_req = RequestProcessor(source, request, relay_state)
     # If the source is configured for Redirect bindings, we can just redirect there
     if source.binding_type == SAMLBindingTypes.REDIRECT:
         # Parse the initial SSO URL
         sso_url = urlparse(source.sso_url)
         # Parse the querystring into a dict...
         url_kwargs = dict(parse_qsl(sso_url.query))
         # ... and update it with the SAML args
         url_kwargs.update(auth_n_req.build_auth_n_detached())
         # Encode it back into a string
         res = ParseResult(
             scheme=sso_url.scheme,
             netloc=sso_url.netloc,
             path=sso_url.path,
             params=sso_url.params,
             query=urlencode(url_kwargs),
             fragment=sso_url.fragment,
         )
         # and merge it back into a URL
         final_url = urlunparse(res)
         return redirect(final_url)
     # As POST Binding we show a form
     try:
         saml_request = nice64(auth_n_req.build_auth_n())
     except InternalError as exc:
         LOGGER.warning(str(exc))
         return bad_request_message(request, str(exc))
     injected_stages = []
     plan_kwargs = {
         PLAN_CONTEXT_TITLE:
         _("Redirecting to %(app)s..." % {"app": source.name}),
         PLAN_CONTEXT_CONSENT_TITLE:
         _("Redirecting to %(app)s..." % {"app": source.name}),
         PLAN_CONTEXT_ATTRS: {
             "SAMLRequest": saml_request,
             "RelayState": relay_state,
         },
         PLAN_CONTEXT_URL:
         source.sso_url,
     }
     # For just POST we add a consent stage,
     # otherwise we default to POST_AUTO, with direct redirect
     if source.binding_type == SAMLBindingTypes.POST:
         injected_stages.append(in_memory_stage(ConsentStageView))
         plan_kwargs[
             PLAN_CONTEXT_CONSENT_HEADER] = f"Continue to {source.name}"
     injected_stages.append(in_memory_stage(AutosubmitStageView))
     return self.handle_login_flow(
         source,
         *injected_stages,
         **plan_kwargs,
     )
コード例 #2
0
ファイル: flows.py プロジェクト: goauthentik/authentik
    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        application: Application = self.executor.plan.context[
            PLAN_CONTEXT_APPLICATION]
        provider: SAMLProvider = get_object_or_404(SAMLProvider,
                                                   pk=application.provider_id)
        if SESSION_KEY_AUTH_N_REQUEST not in self.request.session:
            return self.executor.stage_invalid()

        auth_n_request: AuthNRequest = self.request.session.pop(
            SESSION_KEY_AUTH_N_REQUEST)
        try:
            response = AssertionProcessor(provider, request,
                                          auth_n_request).build_response()
        except SAMLException as exc:
            Event.new(
                EventAction.CONFIGURATION_ERROR,
                message=f"Failed to process SAML assertion: {str(exc)}",
                provider=provider,
            ).from_http(self.request)
            return self.executor.stage_invalid()

        # Log Application Authorization
        Event.new(
            EventAction.AUTHORIZE_APPLICATION,
            authorized_application=application,
            flow=self.executor.plan.flow_pk,
        ).from_http(self.request)

        if provider.sp_binding == SAMLBindings.POST:
            form_attrs = {
                "ACSUrl": provider.acs_url,
                REQUEST_KEY_SAML_RESPONSE: nice64(response),
            }
            if auth_n_request.relay_state:
                form_attrs[
                    REQUEST_KEY_RELAY_STATE] = auth_n_request.relay_state
            return super().get(
                self.request,
                **{
                    "type": ChallengeTypes.NATIVE.value,
                    "component": "ak-stage-autosubmit",
                    "title": "Redirecting to %(app)s..." % {
                        "app": application.name
                    },
                    "url": provider.acs_url,
                    "attrs": form_attrs,
                },
            )
        if provider.sp_binding == SAMLBindings.REDIRECT:
            url_args = {
                REQUEST_KEY_SAML_RESPONSE: deflate_and_base64_encode(response),
            }
            if auth_n_request.relay_state:
                url_args[REQUEST_KEY_RELAY_STATE] = auth_n_request.relay_state
            querystring = urlencode(url_args)
            return redirect(f"{provider.acs_url}?{querystring}")
        return bad_request_message(request, "Invalid sp_binding specified")
コード例 #3
0
ファイル: views.py プロジェクト: vicelikedust/authentik
 def get(self, request: HttpRequest, source_slug: str) -> HttpResponse:
     """Replies with an XHTML SSO Request."""
     source: SAMLSource = get_object_or_404(SAMLSource, slug=source_slug)
     if not source.enabled:
         raise Http404
     relay_state = request.GET.get("next", "")
     auth_n_req = RequestProcessor(source, request, relay_state)
     # If the source is configured for Redirect bindings, we can just redirect there
     if source.binding_type == SAMLBindingTypes.REDIRECT:
         url_args = urlencode(auth_n_req.build_auth_n_detached())
         return redirect(f"{source.sso_url}?{url_args}")
     # As POST Binding we show a form
     saml_request = nice64(auth_n_req.build_auth_n())
     injected_stages = []
     plan_kwargs = {
         PLAN_CONTEXT_TITLE: _("Redirecting to %(app)s..." % {"app": source.name}),
         PLAN_CONTEXT_CONSENT_TITLE: _(
             "Redirecting to %(app)s..." % {"app": source.name}
         ),
         PLAN_CONTEXT_ATTRS: {
             "SAMLRequest": saml_request,
             "RelayState": relay_state,
         },
         PLAN_CONTEXT_URL: source.sso_url,
     }
     # For just POST we add a consent stage,
     # otherwise we default to POST_AUTO, with direct redirect
     if source.binding_type == SAMLBindingTypes.POST:
         injected_stages.append(in_memory_stage(ConsentStageView))
         plan_kwargs[PLAN_CONTEXT_CONSENT_HEADER] = f"Continue to {source.name}"
     injected_stages.append(in_memory_stage(AutosubmitStageView))
     return self.handle_login_flow(
         source,
         *injected_stages,
         **plan_kwargs,
     )