Skip to content

Instantly share code, notes, and snippets.

Last active January 4, 2023 04:18
What would you like to do?
Openedx Keycloak Federated Logout (Single sign out)
parent.postMessage(location.href, location.origin)
{% extends "main_django.html" %}
{% load i18n static %}
{% load django_markup %}
{% block title %}{% trans "Signed Out" as tmsg %}{{ tmsg | force_escape }} | {{ block.super }}{% endblock %}
{% block body %}
{% if show_tpa_logout_link %}
<h1>{% trans "You have signed out." as tmsg %}{{ tmsg | force_escape }}</h1>
<p style="text-align: center; margin-bottom: 20px;">
{% blocktrans trimmed asvar sso_signout_msg %}
{start_anchor}Click here{end_anchor} to delete your single signed on (SSO) session.
{% endblocktrans %}
{% interpolate_html sso_signout_msg start_anchor='<a href="'|add:tpa_logout_url|add:'">'|safe end_anchor='</a>'|safe %}
{% else %}
{% if enterprise_target %}
{% comment %}
For enterprise SSO flow we intentionally drop learner's session.
We are showing this signin message instead of logout message
to avoid any confusion for learner in that case.
{% endcomment %}
<h1>{% trans "We are signing you in." as tmsg %}{{ tmsg | force_escape }}</h1>
<p style="text-align: center; margin-bottom: 20px;">
{% filter force_escape %}
{% blocktrans %}
This may take a minute. If you are not redirected, go to the home page.
{% endblocktrans %}
{% endfilter %}
{% else %}
<h1>{% trans "You have signed out." as tmsg %}{{ tmsg | force_escape }}</h1>
<p style="text-align: center; margin-bottom: 20px;">
{% blocktrans trimmed asvar signout_msg1 %}
If you are not redirected within 5 seconds, {start_anchor}click here to go to the home page{end_anchor}.
{% endblocktrans %}
{% interpolate_html signout_msg1 start_anchor='<a href="'|add:target|add:'">'|safe end_anchor='</a>'|safe %}
{% endif %}
<script type="text/javascript" src="{% static 'js/jquery.allLoaded.js' %}"></script>
<!-- CUSTOM CODE -->
<!-- <script type="text/javascript" src="{% static 'js/logout.js' %}"></script> -->
<script type="text/javascript" src="{% static 'js/keycloak.js' %}"></script>
function initKeycloak() {
const keycloak = new Keycloak({
clientId: 'myclient',
realm: "myrealm",
url: "keycloak.domain",
onLoad: "check-sso",
window.location.origin + "/static/_silent-check-sso.html",
flow: "implicit",
}).then(function(authenticated) {
const params = (new URL(document.location)).searchParams;
const next = params.get('next') || '/'
if (authenticated) {
redirectUri: window.location.origin + next
} else {
window.location = next
}).catch(function() {
alert('failed to initialize');
{% endif %}
<div id="iframeContainer" style="visibility: hidden" data-redirect-url="{{ target }}">
{% for uri in logout_uris %}
<iframe src="{{ uri }}"></iframe>
{% endfor %}
{% endblock body %}
Copy link

maitrungduc1410 commented Jan 3, 2023


Custom logout page of Edx, add small piece of JS code, on logout, use keycloak.js to check Keycloak session then call keycloak.logout()


We're going to add some CUSTOM CODE to the logout.html page

  • Your Keycloak client must enable Implicit Flow
  • in Keycloak, set Valid post logout redirect URIs and Web origins to your Openedx domain, like
  • in Keycloak >Realm Settings > Security Defenses -> Content Security Policy, add your Edx domain to frame-ancestors. Like: frame-src 'self'; frame-ancestors 'self'; object-src 'none';
  • comment <script type="text/javascript" src="{% static 'js/logout.js' %}"></script> in logout.html (as shown in logout.html above)
  • need to mount logout.html to path /openedx/edx-platform/lms/templates/logout.html
  • need to have keycloak.js at path /openedx/staticfiles/js/keycloak.js
  • need to place _silent-check-sso.html at path /openedx/staticfiles/_silent-check-sso.html

keycloak.js can be downloaded here:

Note that paths above are used in Tutor, update accordingly if you're using different paths

Check my gist for federated login here if you want to have SSO with Keycloak

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment