diff --git a/MatrixPlugin.php b/MatrixPlugin.php
index c3b4d05773ffdfebe44b1c264513a15674b8e9e5..c1618ca1e49f0fa7d0643ca4e319b320c7107be5 100644
--- a/MatrixPlugin.php
+++ b/MatrixPlugin.php
@@ -157,10 +157,30 @@ class MatrixPlugin extends StudIPPlugin implements StandardPlugin
         $matrix = MatrixAccount::findOneByUser_id($membership->user_id);
         $room = MatrixRoom::findOneByRange_id($membership->seminar_id);
         if (is_a($matrix, MatrixAccount::class) && is_a($room, MatrixRoom::class)) {
-            MatrixClient::get()->leaveRoom(
-                $matrix->getLinkedAccount(),
-                $room->getLinkedRoom()
-            );
+            /*
+             * leaveRoom can only be used if we don't authorize our Matrix users with SSO and login token stuff.
+             * Otherwise we use the Stud.IP system account to kick the user from the room.
+             */
+            if (Config::get()->MATRIX_SYSTEM_ACCOUNT_ACCESS_TOKEN) {
+                // POST body.
+                $data = [
+                    'user_id' => $matrix->matrix_account_id,
+                    'reason' => sprintf('Not a member of course "%s" anymore.', $membership->course->getFullname())
+                ];
+
+                MatrixClient::get()->requestServer(
+                    sprintf('/_matrix/client/r0/rooms/%s/kick', $room->matrix_room_id),
+                    'POST',
+                    $data,
+                    [],
+                    MatrixAccount::requireSystemAccount()
+                );
+            } else {
+                MatrixClient::get()->leaveRoom(
+                    $matrix->getLinkedAccount(),
+                    $room->getLinkedRoom()
+                );
+            }
         }
     }