mirror of
https://github.com/suitenumerique/meet.git
synced 2026-10-22 12:35:50 +00:00
81876a10d4
We now use `Authorization: Bearer <token>` to authenticate users from the token exchange flow (used for iframe embeds). Until now, the `Bearer` scheme was also reused for the alternative LiveKit authentication, where a client presents its LiveKit token issued by the backend to prove room membership on actions open to any room participant. Sharing the scheme between the two flows is not viable anymore. Switch the LiveKit token authentication to a dedicated `Authorization` scheme, so `Bearer` stays reserved for the iframe / token-exchange flow. Follow-up: a broader effort should look into harmonizing and hardening the backend authentication stack of the app.
59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
"""Authentication using LiveKit token for the Meet core app."""
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.models import AnonymousUser
|
|
|
|
from livekit.api import TokenVerifier
|
|
from rest_framework import authentication, exceptions
|
|
|
|
UserModel = get_user_model()
|
|
|
|
LIVEKIT_AUTH_SCHEME = "X-LiveKit-Token"
|
|
|
|
|
|
class LiveKitTokenAuthentication(authentication.BaseAuthentication):
|
|
"""Authenticate using LiveKit token and load the associated Django user."""
|
|
|
|
def authenticate(self, request):
|
|
auth_header = request.headers.get("Authorization")
|
|
|
|
if not auth_header:
|
|
return None # No authentication attempted
|
|
|
|
parts = auth_header.split()
|
|
if not parts or parts[0].lower() != LIVEKIT_AUTH_SCHEME.lower():
|
|
# Not our scheme (e.g. "Bearer <user access token>"): defer, another
|
|
# backend may recognize it.
|
|
return None
|
|
|
|
if len(parts) != 2:
|
|
raise exceptions.AuthenticationFailed(
|
|
f"Authorization header must be: {LIVEKIT_AUTH_SCHEME} <token>"
|
|
)
|
|
|
|
token = parts[1]
|
|
|
|
try:
|
|
verifier = TokenVerifier(
|
|
api_key=settings.LIVEKIT_CONFIGURATION["api_key"],
|
|
api_secret=settings.LIVEKIT_CONFIGURATION["api_secret"],
|
|
)
|
|
claims = verifier.verify(token)
|
|
|
|
user_id = claims.identity
|
|
if not user_id:
|
|
raise exceptions.AuthenticationFailed("Token missing user identity")
|
|
|
|
try:
|
|
user = UserModel.objects.get(sub=user_id)
|
|
except UserModel.DoesNotExist:
|
|
user = AnonymousUser()
|
|
|
|
return (user, claims)
|
|
|
|
except Exception as e:
|
|
raise exceptions.AuthenticationFailed(
|
|
f"Invalid LiveKit token: {str(e)}"
|
|
) from e
|