def test_report_unknown_issuer(self):
        token = self.create_auth_token(self.user, 'non-existant-issuer',
                                       'some-secret')
        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail == 'Unknown JWT iss (issuer).'
    def test_report_unknown_issuer(self):
        token = self.create_auth_token(self.user, 'non-existant-issuer',
                                       'some-secret')
        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail == 'Unknown JWT iss (issuer).'
    def test_report_token_without_issuer(self):
        payload = self.auth_token_payload(self.user, 'some-issuer')
        del payload['iss']
        token = self.encode_token_payload(payload, 'some-secret')
        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail == 'JWT iss (issuer) claim is missing.'
    def test_report_token_without_issuer(self):
        payload = self.auth_token_payload(self.user, 'some-issuer')
        del payload['iss']
        token = self.encode_token_payload(payload, 'some-secret')
        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail == 'JWT iss (issuer) claim is missing.'
    def test_expired_token(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)
        payload['exp'] = (datetime.utcnow() - timedelta(seconds=10))
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(jwt.ExpiredSignatureError):
            jwt_auth.jwt_decode_handler(token)
    def test_expired_token(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)
        payload['exp'] = (datetime.utcnow() -
                          timedelta(seconds=10))
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(jwt.ExpiredSignatureError):
            jwt_auth.jwt_decode_handler(token)
    def test_missing_expiration(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)
        del payload['exp']
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail == 'Invalid JWT: Token is missing the "exp" claim.'
    def test_missing_expiration(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)
        del payload['exp']
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert (ctx.exception.detail ==
                'Invalid JWT: Token is missing the "exp" claim.')
    def test_incorrect_signature(self):
        api_key = self.create_api_key(self.user)
        token = self.create_auth_token(api_key.user, api_key.key,
                                       api_key.secret)

        decoy_api_key = self.create_api_key(
            self.user, key='another-issuer', secret='another-secret')

        with self.assertRaises(jwt.DecodeError) as ctx:
            jwt_auth.jwt_decode_handler(
                token, get_api_key=lambda **k: decoy_api_key)

        assert ctx.exception.message == 'Signature verification failed'
    def test_invalid_issued_at_time_not_number(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)

        # Simulate clock skew...
        payload['iat'] = 'thisisnotanumber'
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail.startswith(
            'JWT iat (issued at time) is invalid.')
    def test_incorrect_signature(self):
        api_key = self.create_api_key(self.user)
        token = self.create_auth_token(api_key.user, api_key.key,
                                       api_key.secret)

        decoy_api_key = APIKey(  # Don't save in database, it would conflict.
            user=self.user, key=api_key.key, secret='another-secret')

        with self.assertRaises(jwt.DecodeError) as ctx:
            jwt_auth.jwt_decode_handler(
                token, get_api_key=lambda **k: decoy_api_key)

        assert str(ctx.exception) == 'Signature verification failed'
    def test_incorrect_signature(self):
        api_key = self.create_api_key(self.user)
        token = self.create_auth_token(api_key.user, api_key.key,
                                       api_key.secret)

        decoy_api_key = APIKey(  # Don't save in database, it would conflict.
            user=self.user, key=api_key.key, secret='another-secret')

        with self.assertRaises(jwt.DecodeError) as ctx:
            jwt_auth.jwt_decode_handler(
                token, get_api_key=lambda **k: decoy_api_key)

        assert str(ctx.exception) == 'Signature verification failed'
    def test_disallow_long_expirations(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)
        payload['exp'] = (
            datetime.utcnow() +
            timedelta(seconds=settings.MAX_APIKEY_JWT_AUTH_TOKEN_LIFETIME) +
            timedelta(seconds=1))
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail == 'JWT exp (expiration) is too long.'
    def test_invalid_issued_at_time_not_number(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)

        # Simulate clock skew...
        payload['iat'] = 'thisisnotanumber'
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail.startswith(
            'JWT iat (issued at time) is invalid.')
    def test_disallow_long_expirations(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)
        payload['exp'] = (
            datetime.utcnow() +
            timedelta(seconds=settings.MAX_APIKEY_JWT_AUTH_TOKEN_LIFETIME) +
            timedelta(seconds=1)
        )
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail == 'JWT exp (expiration) is too long.'
    def test_invalid_issued_at_time(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)
        # Simulate clock skew:
        payload['iat'] = (
            datetime.utcnow() +
            timedelta(seconds=settings.JWT_AUTH['JWT_LEEWAY'] + 10))
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail.startswith(
            'JWT iat (issued at time) is invalid.')
    def test_invalid_issued_at_time(self):
        api_key = self.create_api_key(self.user)
        payload = self.auth_token_payload(self.user, api_key.key)

        # Simulate clock skew...
        payload['iat'] = datetime.utcnow() + timedelta(
            seconds=settings.JWT_AUTH['JWT_LEEWAY'] + 10)
        token = self.encode_token_payload(payload, api_key.secret)

        with self.assertRaises(AuthenticationFailed) as ctx:
            jwt_auth.jwt_decode_handler(token)

        assert ctx.exception.detail.startswith(
            'JWT iat (issued at time) is invalid.')
    def authenticate(self, request):
        """
        Returns a two-tuple of `User` and token if a valid signature has been
        supplied using JWT-based authentication.  Otherwise returns `None`.

        Copied from rest_framework_jwt BaseJSONWebTokenAuthentication, with
        the decode_handler changed to our own - because we don't want that
        decoder to be the default one in settings - and logging added.
        """
        jwt_value = self.get_jwt_value(request)
        if jwt_value is None:
            return None

        try:
            payload = jwt_auth.jwt_decode_handler(jwt_value)
        except Exception, exc:
            try:
                # Log all exceptions
                log.info('JWTKeyAuthentication failed; '
                         'it raised %s (%s)', exc.__class__.__name__, exc)
                # Re-raise to deal with them properly.
                raise exc
            except jwt.ExpiredSignature:
                msg = ugettext('Signature has expired.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.DecodeError:
                msg = ugettext('Error decoding signature.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.InvalidTokenError:
                msg = ugettext('Invalid JWT Token.')
                raise exceptions.AuthenticationFailed(msg)
Exemple #19
0
    def authenticate(self, request):
        """
        Returns a two-tuple of `User` and token if a valid signature has been
        supplied using JWT-based authentication.  Otherwise returns `None`.

        Copied from rest_framework_jwt BaseJSONWebTokenAuthentication, with
        the decode_handler changed to our own - because we don't want that
        decoder to be the default one in settings - and logging added.
        """
        jwt_value = self.get_jwt_value(request)
        if jwt_value is None:
            return None

        try:
            payload = jwt_auth.jwt_decode_handler(jwt_value)
        except Exception, exc:
            try:
                # Log all exceptions
                log.info('JWTKeyAuthentication failed; '
                         'it raised %s (%s)', exc.__class__.__name__, exc)
                # Re-raise to deal with them properly.
                raise exc
            except jwt.ExpiredSignature:
                msg = _('Signature has expired.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.DecodeError:
                msg = _('Error decoding signature.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.InvalidTokenError:
                msg = _('Invalid JWT Token.')
                raise exceptions.AuthenticationFailed(msg)
    def authenticate(self, request):
        """
        Returns a two-tuple of `User` and token if a valid signature has been
        supplied using JWT-based authentication.  Otherwise returns `None`.

        Copied from rest_framework_jwt BaseJSONWebTokenAuthentication, with
        the decode_handler changed to our own - because we don't want that
        decoder to be the default one in settings - and logging added.
        """
        jwt_value = self.get_jwt_value(request)
        if jwt_value is None:
            return None

        try:
            payload = jwt_auth.jwt_decode_handler(jwt_value)
        except Exception as exc:
            try:
                # Log all exceptions
                log.info('JWTKeyAuthentication failed; '
                         'it raised %s (%s)', exc.__class__.__name__, exc)
                # Re-raise to deal with them properly.
                raise exc
            except TypeError:
                msg = ugettext('Wrong type for one or more keys in payload')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.ExpiredSignature:
                msg = ugettext('Signature has expired.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.DecodeError:
                msg = ugettext('Error decoding signature.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.InvalidTokenError:
                msg = ugettext('Invalid JWT Token.')
                raise exceptions.AuthenticationFailed(msg)
            # Note: AuthenticationFailed can also be raised directly from our
            # jwt_decode_handler.

        user = self.authenticate_credentials(payload)
        # Send user_logged_in signal when JWT is used to authenticate an user.
        # Otherwise, we'd never update the last_login information for users
        # who never visit the site but do use the API to upload new add-ons.
        user_logged_in.send(sender=self.__class__, request=request, user=user)
        return (user, jwt_value)
Exemple #21
0
    def authenticate(self, request):
        """
        Returns a two-tuple of `User` and token if a valid signature has been
        supplied using JWT-based authentication.  Otherwise returns `None`.

        Copied from rest_framework_jwt BaseJSONWebTokenAuthentication, with
        the decode_handler changed to our own - because we don't want that
        decoder to be the default one in settings - and logging added.
        """
        jwt_value = self.get_jwt_value(request)
        if jwt_value is None:
            return None

        try:
            payload = jwt_auth.jwt_decode_handler(jwt_value)
        except Exception as exc:
            try:
                # Log all exceptions
                log.info('JWTKeyAuthentication failed; '
                         'it raised %s (%s)', exc.__class__.__name__, exc)
                # Re-raise to deal with them properly.
                raise exc
            except jwt.ExpiredSignature:
                msg = ugettext('Signature has expired.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.DecodeError:
                msg = ugettext('Error decoding signature.')
                raise exceptions.AuthenticationFailed(msg)
            except jwt.InvalidTokenError:
                msg = ugettext('Invalid JWT Token.')
                raise exceptions.AuthenticationFailed(msg)
            # Note: AuthenticationFailed can also be raised directly from our
            # jwt_decode_handler.

        user = self.authenticate_credentials(payload)
        # Send user_logged_in signal when JWT is used to authenticate an user.
        # Otherwise, we'd never update the last_login information for users
        # who never visit the site but do use the API to upload new add-ons.
        user_logged_in.send(sender=self.__class__, request=request, user=user)
        return (user, jwt_value)
    def test_decode_invalid_non_ascii_token(self):
        with self.assertRaises(jwt.DecodeError) as ctx:
            jwt_auth.jwt_decode_handler(u'Ivan Krsti\u0107')

        assert str(ctx.exception) == 'Not enough segments'
    def test_decode_invalid_non_ascii_token(self):
        with self.assertRaises(jwt.DecodeError) as ctx:
            jwt_auth.jwt_decode_handler(u'Ivan Krsti\u0107')

        assert str(ctx.exception) == 'Not enough segments'
    def test_decode_garbage_token(self):
        with self.assertRaises(jwt.DecodeError) as ctx:
            jwt_auth.jwt_decode_handler('}}garbage{{')

        assert str(ctx.exception) == 'Not enough segments'
    def test_decode_garbage_token(self):
        with self.assertRaises(jwt.DecodeError) as ctx:
            jwt_auth.jwt_decode_handler('}}garbage{{')

        assert str(ctx.exception) == 'Not enough segments'