authentik.providers.oauth2.views.end_session

oauth2 provider end_session Views

 1"""oauth2 provider end_session Views"""
 2
 3from django.http import Http404, HttpRequest, HttpResponse
 4from django.shortcuts import get_object_or_404
 5
 6from authentik.core.models import Application
 7from authentik.flows.models import Flow, in_memory_stage
 8from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlanner
 9from authentik.flows.stage import SessionEndStage
10from authentik.flows.views.executor import SESSION_KEY_PLAN
11from authentik.policies.views import PolicyAccessView
12
13
14class EndSessionView(PolicyAccessView):
15    """Redirect to application's provider's invalidation flow"""
16
17    flow: Flow
18
19    def resolve_provider_application(self):
20        self.application = get_object_or_404(Application, slug=self.kwargs["application_slug"])
21        self.provider = self.application.get_provider()
22        if not self.provider:
23            raise Http404
24        self.flow = self.provider.invalidation_flow or self.request.brand.flow_invalidation
25        if not self.flow:
26            raise Http404
27
28    # If IFrame provider logout happens when a saml provider has redirect
29    # logout enabled, the flow won't make it back without this dispatch
30    def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
31        """Check for active logout flow before policy checks"""
32
33        # Check if we're already in an active logout flow
34        # (being called from an iframe during single logout)
35        if SESSION_KEY_PLAN in request.session:
36            return HttpResponse(
37                "<html><body>Logout successful</body></html>", content_type="text/html", status=200
38            )
39
40        # Otherwise, continue with normal policy checks
41        return super().dispatch(request, *args, **kwargs)
42
43    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
44        """Dispatch the flow planner for the invalidation flow"""
45        planner = FlowPlanner(self.flow)
46        planner.allow_empty_flows = True
47        plan = planner.plan(
48            request,
49            {
50                PLAN_CONTEXT_APPLICATION: self.application,
51            },
52        )
53        plan.append_stage(in_memory_stage(SessionEndStage))
54        return plan.to_redirect(self.request, self.flow)
class EndSessionView(authentik.policies.views.PolicyAccessView):
15class EndSessionView(PolicyAccessView):
16    """Redirect to application's provider's invalidation flow"""
17
18    flow: Flow
19
20    def resolve_provider_application(self):
21        self.application = get_object_or_404(Application, slug=self.kwargs["application_slug"])
22        self.provider = self.application.get_provider()
23        if not self.provider:
24            raise Http404
25        self.flow = self.provider.invalidation_flow or self.request.brand.flow_invalidation
26        if not self.flow:
27            raise Http404
28
29    # If IFrame provider logout happens when a saml provider has redirect
30    # logout enabled, the flow won't make it back without this dispatch
31    def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
32        """Check for active logout flow before policy checks"""
33
34        # Check if we're already in an active logout flow
35        # (being called from an iframe during single logout)
36        if SESSION_KEY_PLAN in request.session:
37            return HttpResponse(
38                "<html><body>Logout successful</body></html>", content_type="text/html", status=200
39            )
40
41        # Otherwise, continue with normal policy checks
42        return super().dispatch(request, *args, **kwargs)
43
44    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
45        """Dispatch the flow planner for the invalidation flow"""
46        planner = FlowPlanner(self.flow)
47        planner.allow_empty_flows = True
48        plan = planner.plan(
49            request,
50            {
51                PLAN_CONTEXT_APPLICATION: self.application,
52            },
53        )
54        plan.append_stage(in_memory_stage(SessionEndStage))
55        return plan.to_redirect(self.request, self.flow)

Redirect to application's provider's invalidation flow

def resolve_provider_application(self):
20    def resolve_provider_application(self):
21        self.application = get_object_or_404(Application, slug=self.kwargs["application_slug"])
22        self.provider = self.application.get_provider()
23        if not self.provider:
24            raise Http404
25        self.flow = self.provider.invalidation_flow or self.request.brand.flow_invalidation
26        if not self.flow:
27            raise Http404

Resolve self.provider and self.application. *.DoesNotExist Exceptions cause a normal AccessDenied view to be shown. An Http404 exception is not caught, and will return directly

def dispatch( self, request: django.http.request.HttpRequest, *args, **kwargs) -> django.http.response.HttpResponse:
31    def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
32        """Check for active logout flow before policy checks"""
33
34        # Check if we're already in an active logout flow
35        # (being called from an iframe during single logout)
36        if SESSION_KEY_PLAN in request.session:
37            return HttpResponse(
38                "<html><body>Logout successful</body></html>", content_type="text/html", status=200
39            )
40
41        # Otherwise, continue with normal policy checks
42        return super().dispatch(request, *args, **kwargs)

Check for active logout flow before policy checks

def get( self, request: django.http.request.HttpRequest, *args, **kwargs) -> django.http.response.HttpResponse:
44    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
45        """Dispatch the flow planner for the invalidation flow"""
46        planner = FlowPlanner(self.flow)
47        planner.allow_empty_flows = True
48        plan = planner.plan(
49            request,
50            {
51                PLAN_CONTEXT_APPLICATION: self.application,
52            },
53        )
54        plan.append_stage(in_memory_stage(SessionEndStage))
55        return plan.to_redirect(self.request, self.flow)

Dispatch the flow planner for the invalidation flow