4

I have a problem with setting up the basic authentication for my AWS lambda function written in Node.js.

The problem:
AWS lambda function which is a proxy for an additional service. This function only forwards the whole request and give the user the whole response. That's why I need to force the usage of the Authentication header and I would like to have the prompt window for passing the credentials: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

Apart from the proxy part of my lambda function, I focused on the problem with authentication and I have written this code:

export const proxy = async (event) => {
    const authorizationHeader = event.headers.Authorization;
    if (typeof authorizationHeader === undefined) {
        throw new Error("Unauthorized");
    }
    ...
};
service:
  name: proxy-auth-test

plugins:
  - serverless-webpack

provider:
  name: aws
  runtime: nodejs8.10
  memorySize: 128
  timeout: 10

functions:
  proxy-async:
    handler: handler.proxy
    events:
      - http:
          method: get
          path: api/proxy

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

The endpoint is working properly, but I can't get the prompt window for passing the credentials. I set up the GatewayResponse according to this https://medium.com/@Da_vidgf/http-basic-auth-with-api-gateway-and-serverless-5ae14ad0a270 but I don't wanna provide the additional lambda function which is responsible only for authorization of the users.

In my case, I can't authorize the users before executing the final lambda function because this function only forwards the request (credentials too), nothing more.

Has anyone ever tried to setup basic auth with the prompt window without the additional authorizer with the usage of serverless and AWS lambda?

2 Answers 2

8

When returning a response from an integration the WWW-Authenticate is remapped to X-Amzn-Remapped-WWW-Authenticate (1). Browsers will not handle this remapped header so they don't show a prompt.

This means that you have to move your authorization logic to the Lambda Authorizer at a HTTP request level and return 'unauthorized' to the callback as stated in the medium link that you referenced. This is the only way to return a WWW-Authenticate header as of now.

Sources:

1: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much!!! It is something that I really wanted to read under this question. Initially, I wanted to do this in another way but finally, I created the custom authorizer and it is working as expected.
1

You are not returning statusCode in the response. The article you are following seems to be using Custom Authorizer that always returns 401 status code with callback('Unauthorized'). Your Lambda function needs to return appropriate error code and headers.

if (typeof authorizationHeader === undefined) {
    return {
        statusCode: 401,
        body: 'unauthorized',
        headers: {
            'WWW-Authenticate': 'Basic'
        }
    }
}

7 Comments

Did you test it before? The code provided by you doesn't work properly and the headers section doesn't conform to the type: [header: string]: boolean | number | string; which is set for APIGatewayProxyResult.headers. The difference between my code and the code provided in the article is that I am using the asynchronous function and I am throwing the error which is the same thing as callback("Unauthorized").
What you are doing is not same as callback("Unauthorized"). Lambda Authorizer will return 401 your Lambda won't. You can try without adding headers key in the response.
I will test it again with sync and async code and give a feedback here, thanks for the quick answer :)
Unfortunately, the response without headers returns 401 as a status code with text Unauthorized on the screen, nothing more (the prompt window doesn't appear). Furthermore, simple callback("Unauthorized") doesn't show the window in the synchronous scope of the function either. Are you sure that it is possible to do it without custom authorizer?
I have tried but I got the same output. Status code -> 401, text on the screen but nothing more. Are you sure that this header didn't disappear somewhere?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.