Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

zappa custom authorizer for flask with cors

I am using flask-cors for a aws python aws lambda API. I deployed it with zappa, it worked as intended. Yet cors does not work with custom authorizer inspired by https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/blob/master/blueprints/python/api-gateway-authorizer-python.py

I changed the authorizer code with try/except and generate a policy for OPTION method on exception, still Option method returns 401.

I do not mind a workaround if it makes things easy.

Thanks

I tried one of suggested solutions: that is to set headers for 401 responses in API Gateway, regretfully browser preflight expects a successful status code.

Update. I felt back on implementing my authorizer, also considered using aws auth service.

like image 961
Serge Avatar asked Nov 01 '17 17:11

Serge


2 Answers

This API Gateway problem (which was confirmed by AWS people) has existed for months.

Luckily, they have recently (June 2017) published a way to fix it using Gateway Responses.


In your API Gateway console, go to your API and then Gateway Responses.

Gateway Responses

Look for Unauthorized (401) and add the following headers (you can use your domains, of course):

Access-Control-Allow-Headers: '*'
Access-Control-Allow-Origin: '*'

See image below:

Unauthorized

like image 114
Noel Llevares Avatar answered Nov 16 '22 23:11

Noel Llevares


  • Getting a 401 from your OPTIONS method in API Gateway is very unusual. I see 403s and missing CORS headers on OPTIONS calls quite a bit, but generally not 401. If there were a problem with your authorizer, I'd expect the 401 on the ensuing POST, not on the OPTIONS call.

  • You also mentioned that you had been changing authorizer code in an effort to handle this.

Without seeing your API Gateway configuration, I can't say for sure, but these two bullet points suggest a possibility. It sounds like your custom authorizer may be hooked up to your OPTIONS method (in addition to POST or whatever you're trying to expose). This shouldn't be the case.

For example, if you attach a custom (token type) authorizer to the OPTIONS method of an API Gateway resource, and then make an OPTIONS call without an Authorization header, you'll get a 401.

Your custom authorizer should only be attached to the methods you're explicitly exposing. In many cases this is just POST, but could include others like PUT, DELETE, and so on.

If this isn't helpful, you might update the question with your API Gateway configuration, and the request/response headers from the failing OPTIONS call.

UPDATE

I deployed a HelloWorld flask app using Zappa, and I think I was able to reproduce your issue. I'm using the blueprint you linked to for the custom authorizer. Changing policy.denyAllMethods() to policy.allowAllMethods() was the only change I made to it.

When I deploy, something like this is created:

APIG configuration without CORS

I was able to get 401 from OPTIONS calls that did not contain an Authorization header.

I added "cors": true to my zappa_settings, which created something much more CORS friendly:

APIG with CORS

This configuration looks better. No more 401 from OPTIONS, whether an Authorization header is present or not.

My zappa_settings with "cors": true added looks like this:

{
    "dev": {
        "app_function": "hello.app",
        "aws_region": "us-east-1",
        "profile_name": null,
        "project_name": "flask",
        "runtime": "python3.6",
        "s3_bucket": "zappa-xxxxxxxxx",
        "cors": true
    },
    "authorizer": {
    "arn": "arn:aws:lambda:us-east-1:xxxxxxxxxxx:function:flask-authorizer",
    "result_ttl": 0
    }
}
like image 34
Mike Patrick Avatar answered Nov 16 '22 23:11

Mike Patrick