Beispiel #1
0
 def handle_login_flow(
     self, source: SAMLSource, *stages_to_append, **kwargs
 ) -> HttpResponse:
     """Prepare Authentication Plan, redirect user FlowExecutor"""
     # Ensure redirect is carried through when user was trying to
     # authorize application
     final_redirect = self.request.session.get(SESSION_KEY_GET, {}).get(
         NEXT_ARG_NAME, "authentik_core:if-admin"
     )
     kwargs.update(
         {
             PLAN_CONTEXT_SSO: True,
             PLAN_CONTEXT_SOURCE: source,
             PLAN_CONTEXT_REDIRECT: final_redirect,
         }
     )
     # We run the Flow planner here so we can pass the Pending user in the context
     planner = FlowPlanner(source.pre_authentication_flow)
     planner.allow_empty_flows = True
     plan = planner.plan(self.request, kwargs)
     for stage in stages_to_append:
         plan.append(stage)
     self.request.session[SESSION_KEY_PLAN] = plan
     return redirect_with_qs(
         "authentik_core:if-flow",
         self.request.GET,
         flow_slug=source.pre_authentication_flow.slug,
     )
Beispiel #2
0
 def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:
     """Verify the SAML Request, and if valid initiate the FlowPlanner for the application"""
     # Call the method handler, which checks the SAML
     # Request and returns a HTTP Response on error
     method_response = self.check_saml_request()
     if method_response:
         return method_response
     # Regardless, we start the planner and return to it
     planner = FlowPlanner(self.provider.authorization_flow)
     planner.allow_empty_flows = True
     plan = planner.plan(
         request,
         {
             PLAN_CONTEXT_SSO: True,
             PLAN_CONTEXT_APPLICATION: self.application,
             PLAN_CONTEXT_CONSENT_HEADER:
             _("You're about to sign into %(application)s.") % {
                 "application": self.application.name
             },
             PLAN_CONTEXT_CONSENT_PERMISSIONS: [],
         },
     )
     plan.append(in_memory_stage(SAMLFlowFinalView))
     request.session[SESSION_KEY_PLAN] = plan
     return redirect_with_qs(
         "authentik_core:if-flow",
         request.GET,
         flow_slug=self.provider.authorization_flow.slug,
     )
Beispiel #3
0
 def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
     """Start FlowPLanner, return to flow executor shell"""
     # After we've checked permissions, and the user has access, check if we need
     # to re-authenticate the user
     if self.params.max_age:
         current_age: timedelta = (
             timezone.now()
             - Event.objects.filter(
                 action=EventAction.LOGIN, user=get_user(self.request.user)
             )
             .latest("created")
             .created
         )
         if current_age.total_seconds() > self.params.max_age:
             return self.handle_no_permission()
     # If prompt=login, we need to re-authenticate the user regardless
     if (
         PROMPT_LOGIN in self.params.prompt
         and SESSION_NEEDS_LOGIN not in self.request.session
     ):
         self.request.session[SESSION_NEEDS_LOGIN] = True
         return self.handle_no_permission()
     # Regardless, we start the planner and return to it
     planner = FlowPlanner(self.provider.authorization_flow)
     # planner.use_cache = False
     planner.allow_empty_flows = True
     scope_descriptions = UserInfoView().get_scope_descriptions(self.params.scope)
     plan: FlowPlan = planner.plan(
         self.request,
         {
             PLAN_CONTEXT_SSO: True,
             PLAN_CONTEXT_APPLICATION: self.application,
             # OAuth2 related params
             PLAN_CONTEXT_PARAMS: self.params,
             # Consent related params
             PLAN_CONTEXT_CONSENT_HEADER: _(
                 "You're about to sign into %(application)s."
             )
             % {"application": self.application.name},
             PLAN_CONTEXT_CONSENT_PERMISSIONS: scope_descriptions,
         },
     )
     # OpenID clients can specify a `prompt` parameter, and if its set to consent we
     # need to inject a consent stage
     if PROMPT_CONSNET in self.params.prompt:
         if not any(isinstance(x, ConsentStageView) for x in plan.stages):
             # Plan does not have any consent stage, so we add an in-memory one
             stage = ConsentStage(
                 name="OAuth2 Provider In-memory consent stage",
                 mode=ConsentMode.ALWAYS_REQUIRE,
             )
             plan.append(stage)
     plan.append(in_memory_stage(OAuthFulfillmentStage))
     self.request.session[SESSION_KEY_PLAN] = plan
     return redirect_with_qs(
         "authentik_core:if-flow",
         self.request.GET,
         flow_slug=self.provider.authorization_flow.slug,
     )