Exemple #1
0
    def authenticate(self, request):
        # auth here is a bytes string type (NOT string)
        auth = get_authorization_header(request).split()

        if not auth or auth[0].lower() != self.keyword.lower().encode():
            return None

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

        try:
            jwt_token = auth[1]
            jwt_info = jwt.decode(jwt_token, settings.SECRET_KEY)
            userid = jwt_info.get('userid')
            try:
                user = User.objects.get(pk=userid)
                return user, jwt_token
            except ValueError:
                msg = 'User dose not exist!'
                raise exceptions.AuthenticationFailed(msg)
        except ExpiredSignatureError:
            msg = 'Token expired!'
            raise exceptions.AuthenticationFailed(msg)
    def authenticate(self, request):
        auth = get_authorization_header(request).split()

        if not auth or auth[0].lower() != self.keyword.lower().encode():
            return None

        if len(auth) == 1:
            msg = 'Authorization 不可用!'
            raise exceptions.AuthenticationFailed(msg)
        elif len(auth) > 2:
            msg = 'Authorization 不可用!提供了过多的参数'
            raise exceptions.AuthenticationFailed(msg)

        try:
            jwt_token = auth[1]
            # 如果解码的时候,发现
            jwt_info = jwt.decode(jwt_token, settings.SECRET_KEY)
            print(jwt_info)
            user_id = jwt_info.get('user_id')
            try:
                user = User.objects.get(pk=user_id)
                return user, jwt_token
            except:
                msg = "用户不存在!"
                raise exceptions.AuthenticationFailed(msg)
        except jwt.ExpiredSignatureError:
            msg = 'Token已经过期了!'
            raise exceptions.AuthenticationFailed(msg)
    def authenticate(self, request):
        auth = get_authorization_header(request).split()

        if not auth or auth[0].lower() != self.keyword.lower().encode():
            msg = _('Add F*****g Token in your ass.')
            raise exceptions.AuthenticationFailed(msg)

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

        try:
            token = auth[1].decode()
        except UnicodeError:
            msg = _(
                'Invalid token header. Token string should not contain invalid characters.'
            )
            raise exceptions.AuthenticationFailed(msg)

        return self.authenticate_credentials(token)
Exemple #4
0
 def authenticate_credentials(self, username, password):
     """
     Authenticate the username and password against username and password.
     """
     user = User.find(username)
     if user is None or not user.is_active():
         raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
     if not user.authenticate(password) and not ldapAuthenticate(username, password):
         raise exceptions.AuthenticationFailed(_('Invalid username/password.'))
     return (user, None)
Exemple #5
0
    def authenticate(self, request):
        user = super().authenticate(request)

        if user.mfa_required:
            if not user.mfa_enabled:
                raise exceptions.AuthenticationFailed("MfaNotEnabled")
            if not request.session.get("mfa_confirmed", False):
                raise exceptions.AuthenticationFailed("MfaNotConfirmed")

        return user, None
Exemple #6
0
 def authenticate_credentials(self, userid, password, request=None):
     """
     Authenticate the userid and password against username and password.
     """
     cass_user = User.find(userid)
     if cass_user is None or not cass_user.is_active():
         raise exceptions.AuthenticationFailed(_("User inactive or deleted."))
     if not cass_user.authenticate(password) and not ldap_authenticate(
         cass_user.uuid, password
     ):
         raise exceptions.AuthenticationFailed(_("Invalid username/password."))
     return (cass_user, None)
Exemple #7
0
def get_payload(request):
    auth = get_authorization_header(request).split()
    if not auth:
        msg = ('缺少AUTHORIZATION或有效的验证凭证')
        raise exceptions.AuthenticationFailed(msg)
    if len(auth) == 1:
        msg = ('无效的token头,缺少有效验证凭证')
        raise exceptions.AuthenticationFailed(msg)
    elif len(auth) > 2:
        msg = ('无效的token头, Token字符串内不能包括空格')
        raise exceptions.AuthenticationFailed(msg)
    contents = auth[1].decode().split(".")
    payload = base64.decodestring(contents[1].encode())
    return json.loads(payload.decode())
Exemple #8
0
    def authenticate_credentials(self, pk):
        """
        Returns user and token if a user with such pk exists and active.
        """
        try:
            user = User.objects.get(pk=pk)
        except User.DoesNotExist:
            msg = _('No user matching this token was found.')
            raise exceptions.AuthenticationFailed(msg, self.exc_name)

        if not user.is_active:
            msg = _('This user has been deactivated.')
            raise exceptions.AuthenticationFailed(msg, self.exc_name)
        return (user, user.token)
    def authenticate(self, request):
        ret = super(TokenAuth, self).authenticate(request)
        # 如果前端没有传Token则报错
        if not ret:
            raise exceptions.AuthenticationFailed(_('Token不存在,请重新登录'))

        return ret
Exemple #10
0
    def authenticate_credentials(self, key):
        model = self.get_model()
        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed(_('Invalid token.'))

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed(
                _('User inactive or deleted.'))

        # 设置token失效时间
        if timezone.now() > (token.created + timedelta(days=1)):
            raise exceptions.AuthenticationFailed(_('Token has expired'))

        return (token.user, token)
Exemple #11
0
    def authenticate_credentials(self, key) -> Tuple[User, str]:
        model = self.get_model()
        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed(_('Wrong authentication token. Please login.'))

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))

        if self.is_token_expired(token):
            raise exceptions.AuthenticationFailed('Your session has expired. Please login again')

        self.update_token_date(token)

        return token.user, token
 def authenticate(self, request):
     ret = {'code': None, 'message': None}
     token = request.META.get('HTTP_X_TOKEN')
     if not token:
         ret['code'] = 1001
         ret['message'] = '请求头错误'
         raise exceptions.AuthenticationFailed(ret)
     token_obj = UserToken.objects.filter(token=token).first()
     if not token_obj or token_obj.expire_in < time.time():
         ret['code'] = 1003
         ret['message'] = 'token过期或不存在,请重新登录'
         raise exceptions.AuthenticationFailed(ret)
     token_obj.expire_in = time.time() + 3600
     token_obj.save()
     user = token_obj.user
     return (user, None)
    def authenticate_credentials(self, key):
        model = self.get_model()
        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed(_('Invalid token.'))

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))

        if self.is_token_expired(token):
            raise exceptions.AuthenticationFailed('Token has expired')

        self.update_token_date(token)

        return token.user, token
Exemple #14
0
    def parse_token(self, request):
        auth = get_authorization_header(request).split()

        if not auth:
            msg = ('缺少AUTHORIZATION或有效的验证凭证')
            raise exceptions.AuthenticationFailed(msg)
        if auth[0].lower() != self.keyword.lower().encode():
            msg = ('缺少或无效的验证凭证前缀,且前缀和凭证之间隔一个空格')
            raise exceptions.AuthenticationFailed(msg)
        if len(auth) == 1:
            msg = ('无效的token头,缺少有效验证凭证')
            raise exceptions.AuthenticationFailed(msg)
        elif len(auth) > 2:
            msg = ('无效的token头, Token字符串内不能包括空格')
            raise exceptions.AuthenticationFailed(msg)
        return auth
Exemple #15
0
    def authenticate_credentials(self, key):
        model = self.get_model()

        try:
            token = model.objects.get(key=key)

        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed('Invalid token.')

        if self.expired(token):
            token.delete()
            raise exceptions.AuthenticationFailed('Token has expired.')

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed('User inactive or deleted.')

        return token.user, token
Exemple #16
0
 def authenticate(self, request):
     if 'HTTP_AUTHORIZATION' in request.META:
         token = request.META['HTTP_AUTHORIZATION'][4:]
         try:
             BlackList.objects.get(token=token)
             raise exceptions.AuthenticationFailed('Unauthorized user')
         except BlackList.DoesNotExist:
             pass
Exemple #17
0
 def authenticate_credentials(self, key) -> Tuple[User, str]:
     user = token_cache.get_user(token=key)
     if user is None:
         msg = 'Wrong authentication token or your session has expired. Please login.'
         logger.error(msg)
         raise exceptions.AuthenticationFailed(ug(msg))
     _, token = token_cache.update(user)
     return user, token
Exemple #18
0
    def authenticate_credentials(self, key):
        user, token = super(TokenAuth, self).authenticate_credentials(key)

        # 设置token失效时间
        if timezone.now() > (token.created +
                             datetime.timedelta(**EXPIRED_TIME)):
            raise exceptions.AuthenticationFailed(_('Token已过期,请重新登录'))

        return user, token
Exemple #19
0
 def authenticate(self, request):
     token = request.query_params.get("token")
     token_obj = UserAuthToken.objects.filter(token=token).first()
     if not token_obj:
         raise exceptions.AuthenticationFailed({
             'code': 9999,
             'error': '认证失败'
         })
     return (token_obj.user, token_obj)
Exemple #20
0
    def authenticate(self, request):
        user = super().authenticate(request)

        if isinstance(user, tuple):
            user = user[0]

        if not user or not user.is_authenticated:
            raise exceptions.AuthenticationFailed("NotLoggedIn")

        return user
def _get_auth_token(request: Request, auth_type):
    """Extract the Bearer token from the 'Authentication' header"""
    header = get_authorization_header(request)
    split = header.split()
    if len(split) == 0:
        return None
    elif len(split) != 2 or split[0].lower() != auth_type:
        raise exceptions.AuthenticationFailed(
            f"Invalid auth header. Format should be '{auth_type} <token>'"
        )
    else:
        return split[1]
def _get_public_key(token, jwks):
    """Find the appropriate JSON Web Key (JWK) to verify this token using RSA"""
    header = jwt.get_unverified_header(token)
    key_id = header.get("kid")

    alg = header.get("alg")
    if not key_id:
        raise exceptions.AuthenticationFailed("Invalid token missing 'kid' header")
    if alg != "RS256":
        raise exceptions.AuthenticationFailed(f"Unsupported 'alg' header {alg}")

    try:
        key = [k for k in jwks["keys"] if k["kid"] == key_id][0]
    except IndexError:
        # If there is an IndexError, the list constructed above probably empty.
        # That likely means the token was generated against a different
        # backend, so the header kid does not appear in our list of jwks keys
        logging.exception("Header key id not present in passed jwks keys")
        raise exceptions.AuthenticationFailed("Forbidden")

    return algorithms.RSAAlgorithm.from_jwk(json.dumps(key))
Exemple #23
0
    def _extract_token(self, auth_header):
        """
        Extracts token from Authentication header.

        Returns None in case if:
          1. header was not found
          2. keyword is incorrect
          3. header contains more or less than 2 'words'(keyword + token)
        """
        if not auth_header or auth_header[0].lower().decode(
        ) != self.keyword.lower():
            return None
        if len(auth_header) == 1:
            msg = _('Invalid token header. No credentials provided.')
            raise exceptions.AuthenticationFailed(msg, self.exc_name)
        elif len(auth_header) > 2:
            msg = _(
                'Invalid token header. Token string should not contain spaces.'
            )
            raise exceptions.AuthenticationFailed(msg, self.exc_name)
        return auth_header[1]
Exemple #24
0
    def authenticate(self, request):
        auth = get_authorization_header(request).split()

        if not auth:
            msg = ('缺少AUTHORIZATION或有效的验证凭证')
            raise exceptions.AuthenticationFailed(msg)
        if auth[0].lower() != self.keyword.lower().encode():
            msg = ('缺少或无效的验证凭证前缀,且前缀和凭证之间隔一个空格')
            raise exceptions.AuthenticationFailed(msg)
        if len(auth) == 1:
            msg = ('无效的token头,缺少有效验证凭证')
            raise exceptions.AuthenticationFailed(msg)
        elif len(auth) > 2:
            msg = ('无效的token头, Token字符串内不能包括空格')
            raise exceptions.AuthenticationFailed(msg)

        try:
            token = auth[1]
            res = jwt.decode(token,
                             Synmetric.PUBLIC_KEY,
                             algorithms=[SYMMETRIC_ENCRYP_ALGORITHM])
            user_id = res.get("user_id")
            try:
                user = User.objects.get(pk=user_id)
            except:
                msg = ('token user不存在!')
                raise exceptions.AuthenticationFailed(msg)
            else:
                return (user, token)
        except jwt.ExpiredSignatureError:
            msg = ('token已过期,请重新获取token!')
            raise exceptions.AuthenticationFailed(msg)
    def authenticate(self, request):
        """Authenticate requests with JWTs from AWS Cognito

        We accept two different types of tokens:

        'id' tokens contain user-identifying information and originate from the
        authorization_code or implicit OAuth2 grants. In this case we return
        the User associated with the token. If the User doesn't exist, we create
        one since we trust Cognito as the source of truth for users in our system.

        'access' tokens do not contain user information and are generated by the
        client_credentials OAuth2 grant. These are not tied to a user but rather
        have 'scopes' that determine what the token can do. We don't support any
        scopes at this point, so we grant this token the privileges of the user
        associated with the API key in the database.
        """
        token = _get_bearer_token(request)
        if not token:
            return None

        token_data = validate_jwt(token)
        token_use = token_data.get("token_use")
        if token_use == "id":
            _validate_id_token_data(token_data)
            username = token_data.get("cognito:username")
            email = token_data.get("email")
            email_verified = token_data.get("email_verified")
            if not email_verified or not email or not username:
                raise exceptions.AuthenticationFailed("Invalid user state")
            try:
                user = User.objects.get_by_natural_key(username)
            except User.DoesNotExist:
                raise exceptions.AuthenticationFailed("User does not exist")
        elif token_use == "access":
            client_id = token_data.get("client_id")

            if not client_id:
                raise exceptions.AuthenticationFailed("Invalid access token")
            try:
                key = APIKey.objects.get(pk=client_id)
                user = key.user
            except APIKey.DoesNotExist:
                raise exceptions.AuthenticationFailed("Invalid access token")
        else:
            raise exceptions.AuthenticationFailed(f"Unknown token_use: {token_use}")

        if not user.is_active:
            raise exceptions.AuthenticationFailed("User deactivated")

        # Only allow admins to impersonate users
        if (
            user.is_admin
            and user.impersonated_user is not None
            and user.id != user.impersonated_user.id
        ):
            # Intentionally don't fire the user_logged_in signal when impersonating
            return user.impersonated_user, token_data

        user_logged_in.send(sender=user.__class__, request=request, user=user)
        return user, token_data
Exemple #26
0
 def authenticate(self, request):
     """
     Authenticate the request and return a two-tuple of (user, token).
     """
     auth_header = get_authorization_header(request).split()
     token = self._extract_token(auth_header)
     if not token:
         return None
     try:
         payload = jwt.decode(token, secret, algorithms=self.ALGORITHMS)
     except jwt.exceptions.InvalidTokenError as e:
         raise exceptions.AuthenticationFailed(e, self.exc_name)
     return self.authenticate_credentials(payload['id'])
Exemple #27
0
    def get_user(self, account_number):
        """Get the Django User for the account number."""
        if not account_number:
            return None

        user = None
        if self.create_user:
            # Note: Declaring this transaction might not be necessary since we have
            # ATOMIC_REQUESTS default to True, but since it's *possible* to disable that
            # setting, this bit of paranoia ensures the User and UserTaskLock are always
            # created together in a shared transaction.
            with transaction.atomic():
                user, created = User.objects.get_or_create(
                    username=account_number)
                if created:
                    user.set_unusable_password()
                    logger.info(
                        _("Username %s was not found and has been created."),
                        account_number,
                    )
                    from api.models import UserTaskLock  # local import to avoid loop

                    UserTaskLock.objects.get_or_create(user=user)
        elif User.objects.filter(username=account_number).exists():
            user = User.objects.get(username=account_number)
            logger.info(
                _("Authentication found user with username %(account_number)s"
                  ),
                {"account_number": account_number},
            )
        elif self.require_user:
            message = _(
                "Authentication Failed: user with account number {username} "
                "does not exist.").format(username=account_number)
            logger.info(message)
            raise exceptions.AuthenticationFailed()
        else:
            logger.info(
                _("Username %s was not found but is not required."),
                account_number,
            )
        logger.debug(
            _("Authenticated user for username %(account_number)s is %(user)s"
              ),
            {
                "account_number": account_number,
                "user": user
            },
        )
        return user
def validate_jwt(token):
    """Validate the signature of the JWT token from Cognito"""
    jwks = get_jwks()
    try:
        return jwt.decode(
            token,
            _get_public_key(token, jwks),
            issuer=settings.COGNITO_USER_POOL_URL,
            algorithms=["RS256"],
            options=JWT_VERIFY_OPTS,
        )
    except jwt.exceptions.PyJWTError:
        # return a generic error message and log the exception, as this might
        # mean that someone is tampering with tokens
        logging.exception("Error decoding JWT token")
        raise exceptions.AuthenticationFailed("Invalid token")
Exemple #29
0
 def authenticate_credentials(self, key):
     cache_key = "username:token:%s" % key
     username = cache.get(cache_key)
     if username is not None:
         # Case 1 - 从缓存正常查找Token
         if TOKEN_TMOUT > 0:
             cache.expire(cache_key, TOKEN_TMOUT)
         user = ExUser.objects.get(username=username)
         return user, None
     elif TOKEN_TMOUT > 0:
         # Case 2 - Token有生命周期且已经过期
         raise exceptions.AuthenticationFailed('Invalid token.')
     else:
         # Case 3 - Token无生命周期, 从DB直接查找(引用框架)
         ret = super(CacheTokenAuthentication, self).authenticate_credentials(key)
         cache.set(cache_key, ret[0].username, timeout=TIMEOUT)
         return ret
Exemple #30
0
 def get_info(self, request):
     auth = get_authorization_header(request).split()
     try:
         token = auth[1]
         res = jwt.decode(token,
                          Synmetric.SECRET,
                          algorithms=[SYMMETRIC_ENCRYP_ALGORITHM])
         return res
         # try:
         #     user = User.objects.get(pk=user_id)
         # except:
         #     msg = ('token user不存在!')
         #     raise exceptions.AuthenticationFailed(msg)
         # else:
         #     return (user, token)
     except jwt.ExpiredSignatureError:
         msg = ('token已过期,请重新获取token!')
         raise exceptions.AuthenticationFailed(msg)