|
1 | 1 | import logging
|
| 2 | +from urllib.parse import urlencode |
2 | 3 |
|
3 | 4 | from django.conf import settings
|
4 | 5 | from django.contrib import auth, messages
|
@@ -97,16 +98,38 @@ def get_success_url(self):
|
97 | 98 |
|
98 | 99 | def get(self, request):
|
99 | 100 | assert self.config_class is not None
|
| 101 | + config = self.config_class.get_solo() |
100 | 102 |
|
101 |
| - if id_token := request.session.get("oidc_id_token"): |
102 |
| - config = self.config_class.get_solo() |
103 |
| - do_op_logout(config, id_token) |
| 103 | + if not (logout_endpoint := config.oidc_op_logout_endpoint): |
| 104 | + logger.warning("No OIDC logout endpoint defined") |
104 | 105 |
|
| 106 | + id_token = request.session.get("oidc_id_token") |
105 | 107 | if "oidc_login_next" in request.session:
|
106 | 108 | del request.session["oidc_login_next"]
|
107 | 109 |
|
| 110 | + # Always destroy our session, having obtained the OIDC artifacts from the session |
108 | 111 | auth.logout(request)
|
109 | 112 |
|
| 113 | + # Try to initiate a frontchannel redirect |
| 114 | + if id_token: |
| 115 | + if not logout_endpoint: |
| 116 | + # Fallback: no frontchannel flow possible |
| 117 | + # TODO: we can actually still redirect here, but it might be a |
| 118 | + # bad UX, because no id token hint. |
| 119 | + do_op_logout(config, id_token) |
| 120 | + else: |
| 121 | + params = { |
| 122 | + "id_token_hint": id_token, |
| 123 | + # The value MUST have been previously registered with the |
| 124 | + # OP, either using the post_logout_redirect_uris |
| 125 | + # Registration parameter or via another mechanism. |
| 126 | + "post_logout_redirect_uri": self.request.build_absolute_uri( |
| 127 | + self.get_success_url() |
| 128 | + ), |
| 129 | + } |
| 130 | + logout_url = f"{logout_endpoint}?{urlencode(params)}" |
| 131 | + return HttpResponseRedirect(logout_url) |
| 132 | + |
110 | 133 | return HttpResponseRedirect(self.get_success_url())
|
111 | 134 |
|
112 | 135 |
|
|
0 commit comments