diff --git a/gregsite/settings/testing.py b/gregsite/settings/testing.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa99b44bf7f7f39459069d64930c32521a7ae72d
--- /dev/null
+++ b/gregsite/settings/testing.py
@@ -0,0 +1,45 @@
+from .base import *
+
+AUTHENTICATION_BACKENDS = [
+    "gregui.authentication.auth_backends.DevBackend",  # Fake dev backend
+    "django.contrib.auth.backends.ModelBackend",  # default
+    "gregui.authentication.auth_backends.GregOIDCBackend",
+    "sesame.backends.ModelBackend",  # link login
+]
+
+OIDC_RP_CLIENT_ID = 'lalalalala'
+OIDC_RP_CLIENT_SECRET = 'lalalalala'
+
+LOGIN_REDIRECT_URL = "http://localhost:3000/"
+LOGOUT_REDIRECT_URL = "http://localhost:3000/"
+
+CSRF_COOKIE_SAMESITE = "Strict"
+SESSION_COOKIE_SAMESITE = "Lax"
+# CSRF_COOKIE_HTTPONLY = True
+# SESSION_COOKIE_HTTPONLY = True
+
+
+ALLOWED_HOSTS += ["localhost", "127.0.0.1"]
+# EMAIL_HOST = "smtp.uio.no"
+# EMAIL_PORT = "468"
+# EMAIL_USE_SSL = True
+# EMAIL_TIMEOUT = 2
+# DEFAULT_FROM_EMAIL = "noreply@uio.no"
+EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
+
+ORGREG_CLIENT = {
+    "endpoints": {"base_url": "https://example.com/fake/"},
+    "headers": {"X-Gravitee-Api-Key": "bar"},
+}
+
+Q_CLUSTER = {
+    "name": "greg",
+    "workers": 4,
+    "timeout": 90,
+    "retry": 120,
+    "queue_limit": 50,
+    "bulk": 10,
+    "orm": "default",
+    "sync": True,
+}
+
diff --git a/gregui/tests/conftest.py b/gregui/tests/conftest.py
index 2213168a9c3820fa8cf3138ac89d10b52d100070..8f98331f2f0882c010cd3d469cfbcfe78251e1df 100644
--- a/gregui/tests/conftest.py
+++ b/gregui/tests/conftest.py
@@ -1,6 +1,7 @@
 import datetime
-import logging
+import time
 
+import logging
 import pytest
 
 
@@ -19,12 +20,107 @@ from greg.models import (
     RoleType,
     Sponsor,
 )
+
 from gregui.models import GregUserProfile
 
 # faker spams the logs with localisation warnings
 # see https://github.com/joke2k/faker/issues/753
 logging.getLogger("faker").setLevel(logging.ERROR)
 
+# OIDC stuff
+@pytest.fixture
+def claims():
+    return {
+        "sub": "subsub",
+        "connect-userid_sec": ["feide:frank_foreleser@spusers.feide.no"],
+        "dataporten-userid_sec": [
+            # "feide:frank_foreleser@spusers.feide.no"
+        ],
+        "name": "Frank Foreleser Føllesen",
+        "email": "noreply@feide.no",
+        "email_verified": True,
+        "picture": "https://api.dataporten.no/userinfo/v1/user/media/p:2192dff7-6989-4244-83cc-ae5e78875bdd",
+    }
+
+
+@pytest.fixture
+def id_token_payload():
+    return {
+        "iss": "https://auth.dataporten.no",
+        "jti": "jtijti",
+        "aud": "lalalalala",
+        "sub": "subsub",
+        "iat": 1605174731,
+        "exp": 1605178331,
+        "auth_time": 1605174731,
+        "nonce": "noncenonce",
+    }
+
+@pytest.fixture
+def data():
+    return {
+        "User": {
+            "user1": {
+                "username": "user1",
+                "email": "user1@example.com",
+            },
+            "user2": {
+                "username": "user2",
+                "email": "user2@example.com",
+            },
+            "https://auth.dataporten.nosubsub": {
+                "username": "https://auth.dataporten.nosubsub",
+            },
+        },
+        "Identity": {
+            "person1": {
+                "type": "feide_id",
+                "value": "foo@example.com",
+                "person": { "email": "foo@example.com" }
+            },
+        },
+        "Person": {
+            "person1": {
+                "first_name": "Foo",
+                "last_name": "Baresen",
+                "email": "foo@example.com",
+            },        
+        },
+        "Sponsor": {
+            "sponsor1": {
+                "first_name": "Bar",
+                "last_name": "Bazesen",
+                "feide_id": "bar@example.com",
+            },
+        },
+    }
+
+
+def save_object(model, **kwargs):
+    obj = model(**kwargs)
+    obj.save()
+    return obj
+
+# TODO add person and sponsor
+OBJECT_MAPPING = {
+    "greg"
+    "person": Person,
+    "sponsor": Sponsor,
+    "user": get_user_model(),
+}
+
+
+def create_objects(cls, data):
+    objects = {}
+    for obj_name, kwargs in data.items():
+        create_kwargs = kwargs.copy()
+        for name, selector in kwargs.items():
+            if name in OBJECT_MAPPING:
+                create_kwargs[name] = OBJECT_MAPPING[name].objects.get(**selector)
+        obj = save_object(cls, **create_kwargs)
+        objects[obj_name] = obj
+    return objects
+
 
 @pytest.fixture
 def client() -> APIClient:
@@ -133,3 +229,32 @@ def invitation_link_expired(invitation, invitation_expired_date) -> InvitationLi
         invitation=invitation, expire=invitation_expired_date
     )
     return InvitationLink.objects.get(id=il.id)
+
+
+def greg_users(data):
+    return create_objects(get_user_model(), data["User"])
+
+
+@pytest.fixture
+def greg_persons(data):
+    return create_objects(get_user_model(), data["Person"])
+
+
+@pytest.fixture
+def greg_sponsors(data):
+    return create_objects(get_user_model(), data["Sponsor"])
+
+
+@pytest.fixture
+def log_in(client, greg_users):
+    def _log_in(username):
+        user = greg_users[username]
+        client.force_login(user=user)
+        # It seems like the session was not updated automatically this way
+        session = client.session
+        session["oidc_id_token_payload"] = {"iat": time.time()}
+        session.save()
+        return client
+
+    return _log_in
+
diff --git a/gregui/tests/test_oidc.py b/gregui/tests/test_oidc.py
new file mode 100644
index 0000000000000000000000000000000000000000..94e755916f6efb4b43b6cb62d74efcfa5521fd89
--- /dev/null
+++ b/gregui/tests/test_oidc.py
@@ -0,0 +1,76 @@
+import time
+import pytest
+
+from django.core.exceptions import SuspiciousOperation
+from django.conf import settings
+
+from greg.models import Identity, Person, Sponsor
+from gregui.authentication.auth_backends import GregOIDCBackend
+from gregui.models import GregUserProfile
+
+
+pytestmark = pytest.mark.django_db
+
+
+def test_validate_issuer(id_token_payload):
+    backend = GregOIDCBackend()
+    backend.validate_issuer(id_token_payload)
+    id_token_payload["iss"] = "http://suspicious.no"
+    with pytest.raises(SuspiciousOperation):
+        backend.validate_issuer(id_token_payload)
+
+
+def test_validate_audiences(id_token_payload):
+    backend = GregOIDCBackend()
+    backend.validate_audience(id_token_payload)
+
+    id_token_payload["aud"] = [id_token_payload["aud"], "other_aud"]
+    with pytest.raises(SuspiciousOperation):
+        backend.validate_audience(id_token_payload)
+
+
+def test_validate_expiry(id_token_payload):
+    backend = GregOIDCBackend()
+    with pytest.raises(SuspiciousOperation):
+        backend.validate_expiry(id_token_payload)
+
+    id_token_payload["exp"] = int(time.time()) + 3600
+    backend.validate_expiry(id_token_payload)
+
+
+def test_filter_users(greg_users, claims):
+    backend = GregOIDCBackend()
+    user = backend.filter_users_by_claims(claims).get()
+    assert user.username == greg_users["https://auth.dataporten.nosubsub"].username
+
+    claims["sub"] = "non-existant-sub"
+    users = backend.filter_users_by_claims(claims)
+    assert len(users) == 0
+
+
+def test_create_user(claims):
+    backend = GregOIDCBackend()
+    user = backend.create_user(claims)
+    assert user.first_name == "Frank Foreleser"
+    assert user.last_name == "Føllesen"
+    assert user.email == "noreply@feide.no"
+
+    userProfile = GregUserProfile.objects.get(user=user)
+    assert userProfile
+
+    person = userProfile.person
+    assert person.first_name == user.first_name
+    assert person.last_name == user.last_name
+    assert person.email == user.email
+
+    ids = Identity.objects.get(person=person, type='feide_id')
+    assert ids.value == 'frank_foreleser@spusers.feide.no'
+
+
+def test_update_user(greg_users, claims):
+    backend = GregOIDCBackend()
+    user = backend.update_user(None, claims)
+
+    assert user.first_name == "Frank Foreleser"
+    assert user.last_name == "Føllesen"
+    assert user.email == "noreply@feide.no"
diff --git a/pytest.ini b/pytest.ini
index a50d688a117f4b733118807805da3de16ce11ce5..a104a9933a8c2350e13ae25c47fa8c53862643f8 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,2 +1,2 @@
 [pytest]
-DJANGO_SETTINGS_MODULE = gregsite.settings.dev
+DJANGO_SETTINGS_MODULE = gregsite.settings.testing