Project

Profile

Help

Issue #3906

Updated by milan over 5 years ago

Pulp's REST API validates that only acceptable fields are submitted with each request. The list of fields does not include the csrf token. As a result of this validation, the browsable API forms produce responses that look like this: 

 <pre> 
     HTTP 400 Bad Request 
     Allow: GET, POST, HEAD, OPTIONS 
     Content-Type: application/json 
     Vary: Accept 
     
     { 
         "csrfmiddlewaretoken": [ 
             "Unexpected field" 
         ] 
     } 

 </pre> 

 We need to investigate how to configure DRF to stop including this field with each form. Otherwise a fix from comment 3 would be appropriate.  

 h3. Notes 

 To easily reproduce, navigate your _browser_ to e.g http://localhost:8000/pulp/api/v3/repositories/ and create a repository by filling-in the create repository form. 
 This happens when "session authentication is used":http://kylebebak.github.io/post/django-rest-framework-auth-csrf such as with a browser; "non-session authentication won't trigger the CSRF protection":http://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication. 
 Unfortunately it seems the session-authentication is somehow mandatory or at least I wasn't able to just switch it off: 

 <pre> 
 pulp: django.request:ERROR: Internal Server Error: /pulp/api/v3/repositories/ 
 Traceback (most recent call last): 
   File "/home/vagrant/.virtualenvs/pulp/lib64/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner 
     response = get_response(request) 
   File "/home/vagrant/.virtualenvs/pulp/lib64/python3.6/site-packages/django/utils/deprecation.py", line 90, in __call__ 
     response = self.process_request(request) 
   File "/home/vagrant/.virtualenvs/pulp/lib64/python3.6/site-packages/django/contrib/auth/middleware.py", line 23, in process_request 
     ) % ("_CLASSES" if settings.MIDDLEWARE is None else "") 
 AssertionError: The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE setting to insert 'django.contrib.sessions.middleware.SessionMiddleware' before 'django.contrib.auth.middleware.AuthenticationMiddleware'. 
 [13/Aug/2018 13:15:14] "GET /pulp/api/v3/repositories/ HTTP/1.1" 500 69693 
 </pre> 

 h3. Discussion 

 The session authentication is configured for particular Django application in @app/settings.py@:  
 <pre><code class="python"> 
 MIDDLEWARE = [ 
   ... 
   django.middleware.csrf.CsrfViewMiddleware, 
   django.contrib.auth.middleware.AuthenticationMiddleware, 
 ] 
 ... 

 REST_FRAMEWORK = { 
   ... 
   'DEFAULT_AUTHENTICATION_CLASSES': [ 
     rest_framework.authentication.SessionAuthentication, 
     rest_framework.authentication.BasicAuthentication, 
   ] 
 } 
 </code></pre> 

 DRF uses a custom authentication class "@SessionAuthentication@":https://github.com/encode/django-rest-framework/blob/version-2.4.x/rest_framework/authentication.py#L129 that in turn utilizes the Django middleware @CsrfViewMiddleware@ class    thru the "@CSRFCheck@":https://github.com/encode/django-rest-framework/blob/version-2.4.x/rest_framework/authentication.py#L30    class, so the "@CsrfViewMiddleware:process_view@":https://github.com/django/django/blob/stable/2.1.x/django/middleware/csrf.py#L205 gets eventually triggered. The @request_csrf_token@ is then extracted from the "@request.POST.get('csrfmiddlewaretoken')@":https://github.com/django/django/blob/stable/2.1.x/django/middleware/csrf.py#L294 form field, which is unset neither in the Django nor in the DRF middleware classes and the @csrfmiddlewaretoken@ form field gets eventually propagated into a Pulp create object view. 

 Good news is we should be fine to just ignore it; "greping" over Github, this particular @csrfmiddlewaretoken@ string "shows quite often in the code":https://github.com/search?q=csrfmiddlewaretoken so often in fact that I can't confirm some of it being DRF/Django workarounds.

Back