This adds the ServiceProvider notion to allow to better manage which teams is available for each service provider.
73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
"""Resource Server Authentication"""
|
|
|
|
import base64
|
|
import binascii
|
|
import logging
|
|
|
|
from django.conf import settings
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
from mozilla_django_oidc.contrib.drf import OIDCAuthentication
|
|
|
|
from .backend import ResourceServerBackend, ResourceServerImproperlyConfiguredBackend
|
|
from .clients import AuthorizationServerClient
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ResourceServerAuthentication(OIDCAuthentication):
|
|
"""Authenticate clients using the token received from the authorization server."""
|
|
|
|
def __init__(self):
|
|
"""Require authentication to be configured in order to instantiate."""
|
|
super().__init__()
|
|
|
|
try:
|
|
authorization_server_client = AuthorizationServerClient(
|
|
url=settings.OIDC_OP_URL,
|
|
verify_ssl=settings.OIDC_VERIFY_SSL,
|
|
timeout=settings.OIDC_TIMEOUT,
|
|
proxy=settings.OIDC_PROXY,
|
|
url_jwks=settings.OIDC_OP_JWKS_ENDPOINT,
|
|
url_introspection=settings.OIDC_OP_INTROSPECTION_ENDPOINT,
|
|
)
|
|
self.backend = ResourceServerBackend(authorization_server_client)
|
|
|
|
except ImproperlyConfigured as err:
|
|
message = "Resource Server authentication is disabled"
|
|
logger.debug("%s. Exception: %s", message, err)
|
|
self.backend = ResourceServerImproperlyConfiguredBackend()
|
|
|
|
def get_access_token(self, request):
|
|
"""Retrieve and decode the access token from the request.
|
|
|
|
This method overrides the 'get_access_token' method from the parent class,
|
|
to support service providers that would base64 encode the bearer token.
|
|
"""
|
|
|
|
access_token = super().get_access_token(request)
|
|
|
|
try:
|
|
access_token = base64.b64decode(access_token).decode("utf-8")
|
|
except (binascii.Error, TypeError):
|
|
pass
|
|
|
|
return access_token
|
|
|
|
def authenticate(self, request):
|
|
"""
|
|
Authenticate the request and return a tuple of (user, token) or None.
|
|
|
|
We override the 'authenticate' method from the parent class to store
|
|
the introspected token audience inside the request.
|
|
"""
|
|
result = super().authenticate(request) # Might raise AuthenticationFailed
|
|
|
|
if result is None: # Case when there is no access token
|
|
return None
|
|
|
|
# Note: at this stage, the request is a "drf_request" object
|
|
request.resource_server_token_audience = self.backend.token_origin_audience
|
|
|
|
return result
|