def test_signing_and_acceptance_of_multiple_algorithms(monkeypatch, user, call_auth_endpoint, rsa_keys): monkeypatch.setattr(api_settings, "JWT_PRIVATE_KEY", rsa_keys["secret"]["rsa1"]) monkeypatch.setattr(api_settings, "JWT_PUBLIC_KEY", rsa_keys["public"]["rsa1"]) for algo in [["HS256", "RS256"], ["RS256", "HS256"]]: monkeypatch.setattr(api_settings, "JWT_ALGORITHM", algo) response = call_auth_endpoint("username", "password") token = response.json()["token"] # check needs to succeed no matter which algo is first algo = [algo[1], algo[0]] monkeypatch.setattr(api_settings, "JWT_ALGORITHM", algo) payload = JSONWebTokenAuthentication.jwt_decode_token(token) assert response.status_code == status.HTTP_201_CREATED assert payload["user_id"] == user.id assert payload["username"] == user.get_username() # changing the signature raises exception token += "a" with raises(InvalidSignatureError): assert JSONWebTokenAuthentication.jwt_decode_token(token) == None
def get_assets_by_user(self, request, *args, **kwargs): """ 根据用户id查看用户资产 """ # Create the instance of JSONWebTokenAuthentication to do the authentication job authentication = JSONWebTokenAuthentication() # try: ''' authentication.authenticate 会抛出异常,所以添加异常捕获 ''' auth_data = authentication.authenticate(request) if auth_data is None: raise exceptions.NotAuthenticated() user = auth_data[0].investor # user_id = request.query_params['id'] # user = get_object_or_404(Investor, pk=user_id) queryset = user.asset_set.all() page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)
def process_request(self, request): """ Override only the request to add the user """ try: return request.user except AttributeError: pass obj = JSONWebTokenAuthentication() try: user_auth_tuple = obj.authenticate(request) except exceptions.APIException: user_auth_tuple = None if user_auth_tuple is not None: request.user, _ = user_auth_tuple # Set last_seen on the user record if it has been > 10 mins # since the record was set. if not request.user.last_seen or ( request.user.last_seen < timezone.now() - timedelta(minutes=LAST_SEEN_DELTA)): request.user.last_seen = timezone.now() request.user.save() return
def validate(self, data): token = data['token'] payload = _check_payload(token=token) user = _check_user(payload=payload) # Get and check 'orig_iat' orig_iat = payload.get('orig_iat') if orig_iat is None: msg = _('orig_iat field not found in token.') raise serializers.ValidationError(msg) # Verify expiration refresh_limit = \ api_settings.JWT_REFRESH_EXPIRATION_DELTA.total_seconds() expiration_timestamp = orig_iat + refresh_limit now_timestamp = unix_epoch() if now_timestamp > expiration_timestamp: msg = _('Refresh has expired.') raise serializers.ValidationError(msg) new_payload = JSONWebTokenAuthentication.jwt_create_payload(user) new_payload['orig_iat'] = orig_iat return { 'token': JSONWebTokenAuthentication.jwt_encode_payload(new_payload), 'user': user, 'issued_at': new_payload.get('iat', unix_epoch()) }
def post(self, request, format=None): try: auth = JSONWebTokenAuthentication() user = auth.authenticate(request=request) if user is not None and user[0].is_superuser: count = Quote.objects.filter(accepted=True).count() quote_id = Quote.objects.filter(accepted=True)[int( random.random() * count)].id try: while quote_id == Daily.objects.latest('date').quote_id: quote_id = Quote.objects.filter(accepted=True)[int( random.random() * count)].id except Daily.DoesNotExist: pass daily = Daily.objects.create(quote_id=quote_id) daily.save() return Response({'status': 'success'}) else: return Response({ 'status': 'Error', 'message': 'Authentication failed' }) except AuthenticationFailed: return Response({ 'status': 'Error', 'message': 'Authentication failed' })
def get_jwt_user(request): user = get_user(request) if user.is_authenticated: return user jwt_authentication = JSONWebTokenAuthentication() if jwt_authentication.get_jwt_value(request): user, jwt = jwt_authentication.authenticate(request) return user
def test_valid_token__returns_new_token(call_auth_refresh_endpoint, user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) payload["exp"] = payload["iat"] + 100 # add 100 seconds to issued at time auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) refresh_response = call_auth_refresh_endpoint(auth_token) refresh_token = refresh_response.json()["token"] assert refresh_token != auth_token
def get_serializer(self, *args, **kwargs): if 'data' in kwargs and 'token' not in kwargs['data']: authorizer = JSONWebTokenAuthentication() jwt_value = authorizer.get_jwt_value(self.request) if jwt_value is not None and len(jwt_value) > 0: kwargs['data']['token'] = jwt_value.decode('utf-8') serializer_class = self.get_serializer_class() kwargs['context'] = self.get_serializer_context() return serializer_class(*args, **kwargs)
def get_user_from_request(request): """ Getting user from User table :param request: :return User or None: """ JWT = JSONWebTokenAuthentication() user, payload = JWT.authenticate(request) return user if user else None
def _create_authenticated_client(user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) token = JSONWebTokenAuthentication.jwt_encode_payload(payload) api_client.credentials( HTTP_AUTHORIZATION="{prefix} {token}".format( prefix=api_settings.JWT_AUTH_HEADER_PREFIX, token=token ) ) return api_client
def get_jwt_user(request): user = get_user(request) # prevent the generation of Token for anonymous user if user.is_authenticated: return user jwt_authentication = JSONWebTokenAuthentication() if jwt_authentication.get_jwt_value(request): user, jwt = jwt_authentication.authenticate(request) return user
def test_auth_refresh__valid_token__returns_new_token(self): payload = JSONWebTokenAuthentication.jwt_create_payload( self.active_user) payload[ 'exp'] = payload['iat'] + 100 # add 100 seconds to issued at time auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) refresh_response = call_auth_refresh_endpoint(self.client, auth_token) refresh_token = refresh_response.json()['token'] self.assertNotEqual(refresh_token, auth_token)
def process_view(self, request, *args): token = request.META.get('HTTP_AUTHORIZATION', '') if not token.startswith('JWT'): return jwt_auth = JSONWebTokenAuthentication() try: request.user = jwt_auth.authenticate(request)[0] except Exception: return
def test_valid_token__returns_new_token_with_new_token_id( call_auth_refresh_endpoint, user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) refresh_response = call_auth_refresh_endpoint(auth_token) refresh_token = refresh_response.json()["token"] refresh_token_payload = JSONWebTokenAuthentication.jwt_decode_token( refresh_token) assert refresh_token_payload["jti"] != str(payload["jti"])
def process_view(self, request, view_func, view_args, view_kwargs): token = request.META.get('HTTP_AUTHORIZATION', None) if token is None: return jwt_auth = JSONWebTokenAuthentication() try: auth = jwt_auth.authenticate(request) request.user = auth[0] except Exception: return
def test_token_with_invalid_username_returns_validation_error( user, call_auth_verify_endpoint): payload = JSONWebTokenAuthentication.jwt_create_payload(user) payload["username"] = "******" auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {"non_field_errors": [_("User doesn't exist.")]} verify_response = call_auth_verify_endpoint(auth_token) assert verify_response.json() == expected_output
def test_refresh_limit_expired__returns_validation_error( call_auth_refresh_endpoint, user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) payload["orig_iat"] = 0 # beginning of time auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {"non_field_errors": [_("Refresh has expired.")]} response = call_auth_refresh_endpoint(auth_token) assert response.json() == expected_output
def test_valid_token__returns_new_token_preserving_original_token_id_for_subsequent_refreshes( call_auth_refresh_endpoint, user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) payload["orig_jti"] = uuid.uuid4() auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) refresh_response = call_auth_refresh_endpoint(auth_token) refresh_token = refresh_response.json()["token"] refresh_token_payload = JSONWebTokenAuthentication.jwt_decode_token( refresh_token) assert refresh_token_payload["orig_jti"] == str(payload["orig_jti"])
def process_view(self, request, view_func, view_args, view_kwargs): token = request.META.get('HTTP_AUTHORIZATION', '') if not token.startswith('JWT'): return jwt_auth = JSONWebTokenAuthentication() auth = None try: auth = jwt_auth.authenticate(request) except Exception: return request.user = auth[0]
def test_valid_token__returns_new_token_preserving_token_id_for_first_refresh( call_auth_refresh_endpoint, user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) assert "orig_jti" not in payload refresh_response = call_auth_refresh_endpoint(auth_token) refresh_token = refresh_response.json()["token"] refresh_token_payload = JSONWebTokenAuthentication.jwt_decode_token( refresh_token) assert refresh_token_payload["orig_jti"] == str(payload["jti"])
def test_expired_token_returns_validation_error(user, call_auth_verify_endpoint): payload = JSONWebTokenAuthentication.jwt_create_payload(user) payload["iat"] = 0 # beginning of time payload["exp"] = 1 # one second after beginning of time auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {"non_field_errors": [_("Token has expired.")]} verify_response = call_auth_verify_endpoint(auth_token) assert verify_response.json() == expected_output
def test_token_without_username_returns_validation_error( user, call_auth_verify_endpoint): payload = JSONWebTokenAuthentication.jwt_create_payload(user) payload.pop("username") auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {"non_field_errors": [_("Invalid token.")]} verify_response = call_auth_verify_endpoint(auth_token) assert verify_response.json() == expected_output
def test_auth_refresh__expired_token__returns_validation_error(self): payload = JSONWebTokenAuthentication.jwt_create_payload( self.active_user) payload['iat'] = 0 payload['exp'] = 1 auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {'non_field_errors': [_('Token has expired.')]} refresh_response = call_auth_refresh_endpoint(self.client, auth_token) self.assertEqual(refresh_response.json(), expected_output)
def test_expired_token__returns_validation_error(call_auth_refresh_endpoint, user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) payload["iat"] = 0 payload["exp"] = 1 auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {"non_field_errors": [_("Token has expired.")]} refresh_response = call_auth_refresh_endpoint(auth_token) assert refresh_response.json() == expected_output
def get_jwt_user(request): try: user = get_user(request) if user.is_authenticated: return user jwt_authentication = JSONWebTokenAuthentication() if jwt_authentication.get_jwt_value(request): user, jwt = jwt_authentication.authenticate(request) except AuthenticationFailed as e: logger.error("Authentication failed: {}".format(e)) return None return user
def test_token_for_inactive_user_returns_validation_error( create_user, call_auth_verify_endpoint): inactive_user = create_user(username="******", password="******", is_active=False) payload = JSONWebTokenAuthentication.jwt_create_payload(inactive_user) auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {"non_field_errors": [_("User account is disabled.")]} verify_response = call_auth_verify_endpoint(auth_token) assert verify_response.json() == expected_output
def test_auth_verify__expired_token__returns_validation_error(self): payload = JSONWebTokenAuthentication.jwt_create_payload( self.active_user) payload['iat'] = 0 # beginning of time payload['exp'] = 1 # one second after beginning of time auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {'non_field_errors': [_('Token has expired.')]} verify_response = call_auth_verify_endpoint(self.client, auth_token) self.assertEqual(verify_response.json(), expected_output)
def test_auth_verify__token_with_invalid_username__returns_validation_error( self): # create token with invalid username payload = JSONWebTokenAuthentication.jwt_create_payload( self.active_user) payload['username'] = "******" auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = {'non_field_errors': [_("User doesn't exist.")]} verify_response = call_auth_verify_endpoint(self.client, auth_token) self.assertEqual(verify_response.json(), expected_output)
def test_view_returns_401_for_corrupt_signature(api_client, user): payload = JSONWebTokenAuthentication.jwt_create_payload(user) token = JSONWebTokenAuthentication.jwt_encode_payload(payload) + "x" api_client.credentials(HTTP_AUTHORIZATION="Bearer " + token) expected_output = {"detail": _("Error decoding token.")} url = reverse("test-view") response = api_client.get(url) assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.json() == expected_output
def test_without_orig_iat_in_payload__returns_validation_error( call_auth_refresh_endpoint, user): # create token without orig_iat in payload payload = JSONWebTokenAuthentication.jwt_create_payload(user) del payload["orig_iat"] auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload) expected_output = { "non_field_errors": [_("orig_iat field not found in token.")] } response = call_auth_refresh_endpoint(auth_token) assert response.json() == expected_output
def process_request(self, request): """ Override only the request to add the user """ try: return request.user except AttributeError: pass obj = JSONWebTokenAuthentication() try: user_auth_tuple = obj.authenticate(request) except exceptions.APIException: user_auth_tuple = None if user_auth_tuple is not None: request.user, _auth = user_auth_tuple return
def process_request(self, request): """ Override only the request to add the user """ try: return request.user except AttributeError: pass obj = JSONWebTokenAuthentication() try: user_auth_tuple = obj.authenticate(request) except exceptions.APIException: user_auth_tuple = None if user_auth_tuple is not None: request.user, _ = user_auth_tuple # Set last_seen on the user record if it has been > 10 mins # since the record was set. if not request.user.last_seen or (request.user.last_seen < timezone.now() - timedelta(minutes=LAST_SEEN_DELTA)): request.user.last_seen = timezone.now() request.user.save() return
def process_response(self, request, response): """ Override only the request to add the new token """ obj = JSONWebTokenAuthentication() try: user_auth_tuple = obj.authenticate(request) except exceptions.APIException: user_auth_tuple = None # Check if request includes valid token if user_auth_tuple is not None: user, _auth = user_auth_tuple # Get the payload details jwt_decode_handler = api_settings.JWT_DECODE_HANDLER payload = jwt_decode_handler(_auth) logging.debug("JWT payload found: {0}".format(payload)) # Check whether we need to renew the token. This will happen if the token # hasn't been renewed in JWT_TOKEN_RENEWAL_DELTA exp = payload.get("exp") created_timestamp = exp - int(api_settings.JWT_EXPIRATION_DELTA.total_seconds()) renewal_timestamp = created_timestamp + int(settings.JWT_TOKEN_RENEWAL_DELTA.total_seconds()) now_timestamp = timegm(datetime.utcnow().utctimetuple()) # If it has been less than JWT_TOKEN_RENEWAL_DELTA time since the # token was created then we will pass on created a renewed token # and just return the response unchanged. if now_timestamp < renewal_timestamp: logging.debug("JWT_TOKEN_RENEWAL_DELTA not exceeded: returning response unchanged.") return response # Get and check orig_iat orig_iat = payload.get("orig_iat") if orig_iat: # verify expiration expiration_timestamp = orig_iat + int(api_settings.JWT_TOKEN_RENEWAL_LIMIT.total_seconds()) if now_timestamp > expiration_timestamp: # Token has passed renew time limit - just return existing # response. We need to test this process because it is # probably the case that the response has already been # set to an unauthorized status # now_timestamp > expiration_timestamp. logging.debug("JWT token has expired: returning response unchanged.") return response else: # orig_iat field is required - just return existing response logging.debug("JWT token orig_iat field not defined: returning response unchanged.") return response jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER new_payload = jwt_payload_handler(user) new_payload["orig_iat"] = orig_iat # Attach the renewed token to the response jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER response["Refresh-Token"] = "JWT {0}".format(jwt_encode_handler(new_payload)) logging.debug("JWT token has been renewed.") return response else: # No authenticated user - just return existing response logging.debug("No JWT authenticated user: returning response unchanged.") return response