Skip to content
This repository has been archived by the owner on Nov 3, 2020. It is now read-only.

Can't access the API with Basic Auth #14

Open
armonge opened this issue Jun 24, 2019 · 4 comments
Open

Can't access the API with Basic Auth #14

armonge opened this issue Jun 24, 2019 · 4 comments

Comments

@armonge
Copy link

armonge commented Jun 24, 2019

I'm trying to use the plugin for some simple auth in a quick flask project. However for some reason i can't get the basic auth to work. For now it's only working when using the x-api-key header

Interestingly seems like there is a change when using a wrong password, meaning the plugin is indeed checking for the password

$ http -a key:bad-password https://something.execute-api.eu-west-1.amazonaws.com/dev/
HTTP/1.1 401 Unauthorized
Connection: keep-alive
Content-Length: 26
Content-Type: application/json
Date: Mon, 24 Jun 2019 15:26:04 GMT
Via: 1.1 5f3006c64f23c42b9bf4b3b63c77aedc.cloudfront.net (CloudFront)
WWW-Authenticate: Basic
X-Amz-Cf-Id: pdkyegI5p9uwYUsNcx7hcByQzz3tIybsEf4cjpAnny7X4f3y2X_A9g==
X-Amz-Cf-Pop: MUC50-C1
X-Cache: Error from cloudfront
x-amz-apigw-id: bym-AHkIjoEFv6A=
x-amzn-ErrorType: UnauthorizedException
x-amzn-RequestId: 6196325d-9694-11e9-9f9e-4bcc800f8014

{
    "message": "Unauthorized"
}

In the case i use a correct password the response changes from "Unauthorized" to "Forbidden"

$ http -a key:good-pass https://something.execute-api.eu-west-1.amazonaws.com/dev/
HTTP/1.1 403 Forbidden
Connection: keep-alive
Content-Length: 23
Content-Type: application/json
Date: Mon, 24 Jun 2019 15:19:28 GMT
Via: 1.1 af3abf09293a5c762de5e451f8d6a913.cloudfront.net (CloudFront)
X-Amz-Cf-Id: f2ytwy0NhZCNu8e8crNouNO8DXK5gmioaaU90NexMvhdyaJUV0taIQ==
X-Amz-Cf-Pop: MUC50-C1
X-Cache: Error from cloudfront
x-amz-apigw-id: bymABEVgjoEF1PA=
x-amzn-ErrorType: ForbiddenException
x-amzn-RequestId: 7524ddb0-9693-11e9-9253-1d415f8ab2fb

{
    "message": "Forbidden"
}

This are the logs i'm getting from the basic_auth lambda

Authentication response: {'principalId': 'my-key-name', 'usageIdentifierKey': 'the value', 'policyDocument': {'Version': '2012-10-17', 'Statement': [{'Action': 'execute-api:Invoke', 'Effect': 'Allow', 'Resource': 'arn:aws:execute-api:eu-west-1:redacted/dev/*'}]}}

And this is the result i get when using x-api-key

$ http https://something.execute-api.eu-west-1.amazonaws.com/dev/ x-api-key:good-pass
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 6374
Content-Type: text/html; charset=utf-8
Date: Mon, 24 Jun 2019 15:26:45 GMT
Via: 1.1 5b3be43b5ff3292b36e9c737ff94254a.cloudfront.net (CloudFront)
X-Amz-Cf-Id: a2xuZm9BKXzmw7mF7fnKTl-KuhthNeA2S6mlpX6cn1Wxof8MUuO4oA==
X-Amz-Cf-Pop: MUC50-C1
X-Amzn-Trace-Id: Root=1-5d10ebb5-92e29a8008a9968073257520;Sampled=0
X-Cache: Miss from cloudfront
x-amz-apigw-id: bynEXELRDoEFnGw=
x-amzn-Remapped-Content-Length: 6374
x-amzn-RequestId: 79d996d0-9694-11e9-95ca-7d989a5d9004

With the corresponding logs:

Authentication response: {'principalId': 'token', 'usageIdentifierKey': 'the value', 'policyDocument': {'Version': '2012-10-17', 'Statement': [{'Action': 'execute-api:Invoke', 'Effect': 'Allow', 'Resource': 'arn:aws:execute-api:eu-west-1:redacted/dev/*'}]}}

The only difference i can find is the principalId value

For reference here's my serverless.yml

service: some-project

provider:
  name: aws
  iamRoleStatements:
    - Effect: Allow
      Action:
        - apigateway:GET
      Resource: "*"
  apiKeys:
    - key

plugins:
  - serverless-wsgi
  - serverless-python-requirements
  - serverless-basic-authentication
  - serverless-apigw-binary

custom:
  wsgi:
    app: app.app
    packRequirements: false

  apigwBinary:
    types:
      - 'multipart/form-data'

functions:
  app:
    handler: wsgi_handler.handler
    runtime: python3.7
    events:
      - http:
          path: /
          method: ANY
          private: true
      - http: 
          path: '{proxy+}'
          method: ANY
          private: true

resources:
  Resources:
    GatewayResponse:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.WWW-Authenticate: "'Basic'"
        ResponseType: UNAUTHORIZED
        RestApiId:
          Ref: 'ApiGatewayRestApi'
        StatusCode: '401'
@svdgraaf
Copy link
Owner

afaik, the response for the password authorizer is correct, it should return the token id as principal id...

@svdgraaf
Copy link
Owner

Sorry, I meant usageIdentifierKey. That is used to identify which token is used:

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html

The output is actually correct, the fact that you get a Forbidden instead of Unauthorized means that api gateway actually accepted the response as well...

You can check if this is not a problem with your backend through the "Test" feature in api gateway, there you can see if the problem is still there when access the backend directly, as this bypasses the custom authorizer.

@armonge
Copy link
Author

armonge commented Jun 25, 2019

Interestingly enough, the API gateway and the application work correctly (minus auth of course) when i remove the serverless-basic-authentication plugin. I also tested using the "Test" feature and serverless-basic-authentication enabled, the API Gateway response is the one i'm expecting from my backend

Also, even with serverless-basic-authentication enabled the backend does produce the expected result when using the x-api-key header.

http https://something.execute-api.eu-west-1.amazonaws.com/dev/ x-api-key:good-pass

The issue only happens with 'Basic Auth'

@rilian
Copy link

rilian commented Aug 15, 2019

i am having similar issue. with plugin attached, all existing endpoints that have private: true in function definition return {message: null} after 30 seconds, and all inexisting endpoints return this interesting message:

{"message":"Authorization header requires 'Credential' parameter. 
Authorization header requires 'Signature' parameter. 
Authorization header requires 'SignedHeaders' parameter. 
Authorization header requires existence of either 
a 'X-Amz-Date' or a 'Date' header. 
Authorization=Basic Zm9vYmFyOg=="}

i have decrypted this base64 string Zm9vYmFyOg== and it is foobar: - i definitely have no such string in my codebase.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants