core: add new token intent and auth backend
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
aad753de68
commit
20572c728d
|
@ -408,6 +408,9 @@ class TokenIntents(models.TextChoices):
|
|||
# Recovery use for the recovery app
|
||||
INTENT_RECOVERY = "recovery"
|
||||
|
||||
# App-specific passwords
|
||||
INTENT_APP_PASSWORD = "app_password"
|
||||
|
||||
|
||||
class Token(ManagedModel, ExpiringModel):
|
||||
"""Token used to authenticate the User for API Access or confirm another Stage like Email."""
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
"""Authenticate with tokens"""
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.contrib.auth.backends import ModelBackend
|
||||
from django.http.request import HttpRequest
|
||||
|
||||
from authentik.core.models import Token, TokenIntents, User
|
||||
|
||||
|
||||
class TokenBackend(ModelBackend):
|
||||
"""Authenticate with token"""
|
||||
|
||||
def authenticate(
|
||||
self, request: HttpRequest, username: Optional[str], password: Optional[str], **kwargs: Any
|
||||
) -> Optional[User]:
|
||||
try:
|
||||
user = User._default_manager.get_by_natural_key(username)
|
||||
except User.DoesNotExist:
|
||||
# Run the default password hasher once to reduce the timing
|
||||
# difference between an existing and a nonexistent user (#20760).
|
||||
User().set_password(password)
|
||||
return None
|
||||
tokens = Token.filter_not_expired(
|
||||
user=user, key=password, intent=TokenIntents.INTENT_APP_PASSWORD
|
||||
)
|
||||
if not tokens.exists():
|
||||
return None
|
||||
return user
|
|
@ -1,3 +1,4 @@
|
|||
"""Backend paths"""
|
||||
BACKEND_DJANGO = "django.contrib.auth.backends.ModelBackend"
|
||||
BACKEND_LDAP = "authentik.sources.ldap.auth.LDAPBackend"
|
||||
BACKEND_TOKEN = "authentik.core.token_auth.TokenBackend"
|
||||
|
|
|
@ -9,7 +9,7 @@ from rest_framework.serializers import BaseSerializer
|
|||
|
||||
from authentik.core.types import UserSettingSerializer
|
||||
from authentik.flows.models import ConfigurableStage, Stage
|
||||
from authentik.stages.password import BACKEND_DJANGO, BACKEND_LDAP
|
||||
from authentik.stages.password import BACKEND_DJANGO, BACKEND_LDAP, BACKEND_TOKEN
|
||||
|
||||
|
||||
def get_authentication_backends():
|
||||
|
@ -17,11 +17,15 @@ def get_authentication_backends():
|
|||
return [
|
||||
(
|
||||
BACKEND_DJANGO,
|
||||
_("authentik-internal Userdatabase"),
|
||||
_("User database + standard password"),
|
||||
),
|
||||
(
|
||||
BACKEND_TOKEN,
|
||||
_("User database + app passwords"),
|
||||
),
|
||||
(
|
||||
BACKEND_LDAP,
|
||||
_("authentik LDAP"),
|
||||
_("User database + LDAP password"),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
Reference in New Issue