diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 109db7158ede8899691b65c179d0298dee79d6c3..d076019ea175fcc03be612154af937bc655605ef 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -246,6 +246,20 @@ class Person(ExtensibleModel):
                 self.primary_group = self.member_of.filter(name__regex=pattern).first()
 
 
+class DummyPerson(Person):
+    """ A dummy person that is not stored into the database.
+
+    Used to temporarily inject a Person object into a User.
+    """
+
+    class Meta:
+        managed = False
+        proxy = True
+
+    def save(self, *args, **kwargs):
+        pass
+        
+
 class Group(ExtensibleModel):
     """Any kind of group of persons in a school, including, but not limited
     classes, clubs, and the like.
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 6fd8e14951bb0585f2138a37fe384d726f0b4ccc..9d8cf2acfa3e1f9cea3ccde4e1cddfcd95572fa5 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -117,6 +117,7 @@ MIDDLEWARE = [
     "django.middleware.common.CommonMiddleware",
     "django.middleware.csrf.CsrfViewMiddleware",
     "django.contrib.auth.middleware.AuthenticationMiddleware",
+    "aleksis.core.util.middlewares.EnsurePersonMiddleware",
     "debug_toolbar.middleware.DebugToolbarMiddleware",
     "django_otp.middleware.OTPMiddleware",
     "impersonate.middleware.ImpersonateMiddleware",
diff --git a/aleksis/core/util/middlewares.py b/aleksis/core/util/middlewares.py
new file mode 100644
index 0000000000000000000000000000000000000000..49d5c2e3eb6a2c36b4f7d2bdcfc915487ff8bee1
--- /dev/null
+++ b/aleksis/core/util/middlewares.py
@@ -0,0 +1,33 @@
+from typing import Callable
+
+from django.core.exceptions import PermissionDenied
+from django.http import HttpRequest, HttpResponse
+from django.util.translation import gettext_lazy as _
+
+from .core_helpers import has_person
+from .messages import warning
+from ..models import DummyPerson
+
+
+class EnsurePersonMiddleware:
+    """ Middleware that ensures that the logged-in user is linked to a person.
+
+    It is needed to inject a dummy person to a superuser that would otherwise
+    not have an associated person, in order they can get their account set up
+    without external help.
+    """
+
+    def __init__(self, get_response: Callable):
+        self.get_response = get_response
+
+    def __call__(self, request: HttpRequest) -> HttpResponse:
+        if not has_person(request):
+            if request.user.is_superuser:
+                # Super-users get a dummy person linked
+                dummy_person = DummyPerson(first_name=request.user.first_name, last_name=request.user.last_name)
+                request.user.person = dummy_person
+
+                warning(request, _("A dummy user has been linked to your user account."))
+
+        response = self.get_response(request)
+        return response