Beispiel #1
0
    def __init__(self):
        self._jwt_validator = TokenValidator(
            settings.COGNITO_AWS_REGION,
            settings.COGNITO_USER_POOL,
            settings.COGNITO_AUDIENCE)

        super().__init__()
Beispiel #2
0
    def get(self, request, format=None, **kwargs):
        if settings.COGNITO_ENABLED is False:
            body = {"message": "page not found"}
            return Response(body, status=status.HTTP_404_NOT_FOUND)
        else:
            body = {"message": "page found"}
            code = request.query_params.get("code", None)
            if code is None:
                return Response({"message": "Not Found"},
                                status=status.HTTP_404_NOT_FOUND)

            redirect_uri = request.build_absolute_uri('?')
            redirect_uri = redirect_uri.rstrip('/')

            token_resp = requests.post(
                "https://" + settings.COGNITO_DOMAIN + "/oauth2/token",
                data={
                    "grant_type": "authorization_code",
                    "client_id": settings.COGNITO_AUDIENCE,
                    "code": code,
                    "scope": "openid",
                    "redirect_uri": redirect_uri
                })
            try:
                aws = token_resp.json()
                response = {"aws": aws}
                if token_resp.status_code != 200:
                    logger.error(f"AWS returned {aws}")
                    return Response(
                        {
                            "aws error": aws,
                            "status": token_resp.status_code
                        },
                        status=token_resp.status_code)
                id_token = aws['id_token']
                validator = TokenValidator(settings.COGNITO_AWS_REGION,
                                           settings.COGNITO_USER_POOL,
                                           settings.COGNITO_AUDIENCE)
                jwt_payload = validator.validate(id_token)
                response.update({"jwt": jwt_payload})
                user = User.objects.get_or_create_for_cognito(jwt_payload)
                response.update({"user": user.username})

                # Upgrade the connection to a session
                login(request, user)

                # Use this to get id_token for debug
                #return Response({"id_token": id_token})
                return redirect("/projects")
            except TokenError as e:
                return Response({"message": "invalid token"},
                                status=status.HTTP_404_NOT_FOUND)
Beispiel #3
0
class JSONWebTokenAuthentication(BaseAuthentication):
    """Token based authentication using the JSON Web Token standard."""
    def __init__(self):
        self._jwt_validator = TokenValidator(settings.COGNITO_AWS_REGION,
                                             settings.COGNITO_USER_POOL,
                                             settings.COGNITO_AUDIENCE)

        super().__init__()

    def authenticate(self, request):
        """Entrypoint for Django Rest Framework"""
        jwt_token = self.get_jwt_token(request)
        if jwt_token is None:
            return None

        # Authenticate token
        try:
            jwt_payload = self._jwt_validator.validate(jwt_token)
        except TokenError:
            raise exceptions.AuthenticationFailed()

        user = USER_MODEL.objects.get_or_create_for_cognito(jwt_payload)
        return (user, jwt_token)

    def get_jwt_token(self, request):
        auth = get_authorization_header(request).split()
        if not auth or smart_text(auth[0].lower()) != 'bearer':
            return None

        if len(auth) == 1:
            msg = _('Invalid Authorization header. No credentials provided.')
            raise exceptions.AuthenticationFailed(msg)
        elif len(auth) > 2:
            msg = _('Invalid Authorization header. Credentials string '
                    'should not contain spaces.')
            raise exceptions.AuthenticationFailed(msg)

        return auth[1]

    def authenticate_header(self, request):
        """
        Method required by the DRF in order to return 401 responses for authentication failures, instead of 403.
        More details in https://www.django-rest-framework.org/api-guide/authentication/#custom-authentication.
        """
        return 'Bearer: api'
Beispiel #4
0
class JSONWebTokenAuthentication(BaseAuthentication):
    """Token based authentication using the JSON Web Token standard."""

    def __init__(self):
        self._jwt_validator = TokenValidator(
            settings.COGNITO_AWS_REGION,
            settings.COGNITO_USER_POOL,
            settings.COGNITO_AUDIENCE)

        super().__init__()

    def authenticate(self, request):
        """Entrypoint for Django Rest Framework"""
        jwt_token = self.get_jwt_token(request)
        if jwt_token is None:
            return None

        # Authenticate token
        try:
            jwt_payload = self._jwt_validator.validate(jwt_token)
        except TokenError:
            raise exceptions.AuthenticationFailed()

        get_or_create_for_cognito_code = '{function_name}(jwt_payload, request)'.format(
            function_name=settings.COGNITO_GET_USER_OR_CREATE_FUNCTION, jwt_payload=jwt_payload, request=request)

        user = eval(get_or_create_for_cognito_code)
        return (user, jwt_token)

    def get_jwt_token(self, request):
        auth = get_authorization_header(request).split()
        if not auth or smart_text(auth[0].lower()) != settings.COGNITO_AUTH_HEADER:
            return None

        if len(auth) == 1:
            msg = _('Invalid Authorization header. No credentials provided.')
            raise exceptions.AuthenticationFailed(msg)
        elif len(auth) > 2:
            msg = _('Invalid Authorization header. Credentials string '
                    'should not contain spaces.')
            raise exceptions.AuthenticationFailed(msg)

        return auth[1]
 def get_token_validator(self):
     return TokenValidator(
         settings.COGNITO_AWS_REGION,
         settings.COGNITO_USER_POOL,
         settings.COGNITO_AUDIENCE,
     )