16

EDIT: Read further down for two solutions.

I have deployed a Flask app to AWS ElasticBeanstalk. The app is unable to read the 'Authorization' header in requests.

Error log reports:

KeyError: 'HTTP_AUTHORIZATION'

Error traced to:

@application.before_request
    def before_request():
       try:
          token = request.headers['Authorization'].split(' ')[-1]
          user = User.get(token=token)
          g.user = user
       except ValueError as e:
        abort(401)

Application directory:

app/
    .elasticbeanstalk
    application.py
    virt
    .ebignore
    requirements.txt

Environment configuration sets the WSGIPath to application.py:

aws:elasticbeanstalk:container:python:
 NumProcesses: '1'
 NumThreads: '15'
 StaticFiles: /static/=static/
 WSGIPath: application.py

Environment runs Python 3.6 and the following components:

Click==7.0
Flask==1.0.2
Flask-RESTful==0.3.7
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.1
peewee==3.9.2
psycopg2==2.7.7
python-dotenv==0.10.1
pytz==2018.9
six==1.12.0
Werkzeug==0.14.1

Is anything else required?

Attempted (unsuccessful) solution:

I have burnt many hours on this, and have attempted to configure WSGIPassAuthorization, (as per advice here and elsewhere) however, I have not been successful.

Application directory containing workaround:

app/
    .elasticbeanstalk
    .ebextensions/
        wsgi_custom.config
    application.py
    virt
    .ebignore
    requirements.txt

When I attempt to create the eb environment containing .ebextensions/wsgi_custom.config the EB CLI reports an error saying that the YAML is not valid:

    ERROR: InvalidParameterValueError - The configuration file .ebextensions/wsgi_custom.config in application version app-190310_100513 contains invalid YAML or JSON. YAML exception: Invalid Yaml: while scanning a simple key
 in "<reader>", line 7, column 5:
        WSGIPassAuthorization On
        ^
could not found expected ':'
 in "<reader>", line 7, column 29:
    On
      ^
, JSON exception: Invalid JSON: Unexpected character (f) at position 0.. Update the configuration file.

Contents of .ebextensions/wsgi_custom.config:

    files:
       "/etc/httpd/conf.d/wsgi_custom.conf":
         mode: "000644"
         owner: root
         group: root
         content: |
           WSGIPassAuthorization On

My YAML validation tool reports valid YAML.

Note: editor is set to use spaces, as per AWS YAML advice.

EDIT: SOLUTION 1

Solved YAML validation errors in the example above. I believe the validation errors were a red herring. The .conf file mentioned in the script now has a valid name.

Contents of .ebextensions/wsgi_custom.config:

    files:
  "/etc/httpd/conf.d/wsgihacks.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      WSGIPassAuthorization On

EDIT: SOLUTION 2 using container_commands

Set WSGIPassAuthorization on ElasticBeanstalk using container_commands.

Step 1. Create .ebextensions/wsgi_custom.config:

app/
    .elasticbeanstalk
    .ebextensions/
        wsgi_custom.config
    application.py
    virt
    .ebignore
    requirements.txt

wsgi_custom.config:

container_commands:
    01wsgipass:
        command: 'echo "WSGIPassAuthorization On" >> ../wsgi.conf'

Step 2. Restart EB environment.

Flask app can now read 'Authorization' header in requests.

Hooray :)

If anyone can point me to a lucid discussion about WSGI it would be appreciated.

burntsugar
  • 54,120
  • 21
  • 51
  • 77

0 Answers0