diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index d94610cf958f0284cfde273c1c6fbc2cdc747a4e..e3bf169d47bcc085dda0257fa136902247b90b90 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -44,6 +44,7 @@ Added
 * Tooltips for every information in the person page
 * New menu item "Data management" with Rooms, Announcements, Holidays, and School Terms
 * Priority to sort announcements
+* Allow matching social accounts to local accounts by their username.
 
 Changed
 ~~~~~~~
@@ -67,7 +68,7 @@ Fixed
 * Opening group details wasn't possible without permissions for all person details.
 * [Dev] Foreign keys to ExtensiblePolymorphicModel types were using the wrong manager.
 * [Dev] Allow activating more frequent polling for Celery task progress.
-* [OIDC] Custom additional claims were not present in userinfo 
+* [OIDC] Custom additional claims were not present in userinfo
 * Synchronisation of AlekSIS and Django groups caused permissions issues
 * Permission checks for dashboard widget creation and person invitations were invalid
 * New Persons were not added to selected primary group on creation
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 01b092f20b1a54cdd71d03112e46b99da15c78f2..83ce6d2c45d4a125afd7f21a4e16cf1d80ae372e 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -327,6 +327,9 @@ if _SOCIALACCOUNT_PROVIDERS:
         INSTALLED_APPS.append(f"allauth.socialaccount.providers.{provider}")
         SOCIALACCOUNT_PROVIDERS[provider] = {k.upper(): v for k, v in config.items()}
 
+ALEKSIS_SOCIALACCOUNT_USERNAME_MATCHING = _settings.get(
+    "auth.socialaccount_username_matching", False
+)
 
 # Configure custom forms
 
diff --git a/aleksis/core/util/auth_helpers.py b/aleksis/core/util/auth_helpers.py
index b947835e3e6439d8aea89cef1bcd85a1d4dee1b6..97016b36d3c2d07d68e87ed43be5a41a952f4d60 100644
--- a/aleksis/core/util/auth_helpers.py
+++ b/aleksis/core/util/auth_helpers.py
@@ -1,8 +1,10 @@
 """Helpers/overrides for django-allauth."""
 
+import logging
 from typing import Any, Optional
 
 from django.conf import settings
+from django.contrib.auth import get_user_model
 from django.contrib.auth.validators import ASCIIUsernameValidator
 from django.core.exceptions import ValidationError
 from django.core.validators import RegexValidator
@@ -26,6 +28,21 @@ from .core_helpers import get_site_preferences
 class OurSocialAccountAdapter(DefaultSocialAccountAdapter):
     """Customised adapter that recognises other authentication mechanisms."""
 
+    def pre_social_login(self, request, sociallogin):
+        # Try to match social accounts to local accounts by their username if enabled
+        if (
+            settings.ALEKSIS_SOCIALACCOUNT_USERNAME_MATCHING
+            and not sociallogin.is_existing
+            and sociallogin.account.extra_data.get("preferred_username")
+        ):
+            username = sociallogin.account.extra_data["preferred_username"]
+            try:
+                user = get_user_model().objects.get(username=username)
+                sociallogin.user = user
+                logging.info(f"Match local account {username} to social account")
+            except get_user_model().DoesNotExist:
+                pass
+
     def validate_disconnect(self, account, accounts):
         """Validate whether or not the socialaccount account can be safely disconnected.
 
diff --git a/docs/_static/create_social_application.png b/docs/_static/create_social_application.png
deleted file mode 100644
index c28c5c30a6d71f8aa0f1177b92048449c688d113..0000000000000000000000000000000000000000
Binary files a/docs/_static/create_social_application.png and /dev/null differ
diff --git a/docs/admin/23_socialaccounts.rst b/docs/admin/23_socialaccounts.rst
index 97f2fc7bb15c59f7cbac769759c6a485122e5ea8..11b8f95ccc323e08211c6597f781b112862243d1 100644
--- a/docs/admin/23_socialaccounts.rst
+++ b/docs/admin/23_socialaccounts.rst
@@ -7,7 +7,7 @@ or OpenID.
 This can be used to grant access to persons whose credentials shall not be
 managed in AlekSIS itself, for example because another authentication provider
 is already used throughout the school, or for guardians that can or should for
-some reason not get an LDAP account, or similar situations.
+some reason not get a local account, or similar situations.
 
 .. warning::
   Social accounts are **not** working with two factor authentication! If a user
@@ -18,21 +18,39 @@ Configuring social account provider
 -----------------------------------
 
 For available providers, see documentation of `django-allauth
-<https://django-allauth.readthedocs.io/en/latest/providers.html>`_.
+<https://docs.allauth.org/en/latest/socialaccount/providers/index.html>`_.
 
 A new social account provider can be configured in your configuration file
 (located in ``/etc/aleksis/``).
 
-Configuration example::
+Configuration examples::
 
-  [auth.providers.gitlab]
-  GITLAB_URL = "https://gitlab.exmaple.com"
+  # GitLab
+  [[auth.providers.gitlab.APPS]]
+  client_id = "<client_id>"
+  secret = "<client_secret>"
+  settings = { gitlab_url = "https://gitlab.example.com" }
 
-After configuring a new auth provider, you have to restart AlekSIS and configure client id and secret in the Backend Admin interface.
-Click "Social applications" and add a new application. Choose your
-provider and enter client id and secret from your application and choose
-your site:
+  # Generic OpenID Connect
+  [[auth.providers.openid_connect.APPS]]
+  client_id = '<client_id>'
+  secret = '<client_secret>'
+  name = 'Service Name'
+  provider_id = 'service_name'
+  settings = { server_url =  'https://example.org' }
 
-.. image:: ../_static/create_social_application.png
-  :width: 100%
-  :alt: Create social application
+After configuring a new authentication provider, you have to restart AlekSIS.
+
+Match local accounts to social accounts by username
+---------------------------------------------------
+
+You can configure AlekSIS to automatically match local accounts to social accounts
+by their username. To do this, set the following configuration::
+
+  [auth]
+  socialaccount_username_matching = true
+
+.. warning::
+  Only activate this behavior, if you are completely sure
+  that you want to match local accounts to social accounts
+  by their username and that the third-party provider can be trusted.