Sagar Jani
Sagar Jani

Reputation: 297

How to exempt certain resource from custom authorization in AWS API Gateway ?

I have configured custom authorization in API gateway for a proxy resource but my requirement is to exempt few APIs from authorization, but I don't want to configure a new API in API gateway because I'm trying to design a proxy through API gateway.

For Example, the API /server/ver1.0/rest/{proxy+}, this is my REST API configured in API gateway which goes through custom authorizer and then if it's successful then it invokes backend http service.

But I would like to exempt the API - /server/ver1.0/rest/acc/reg from authorization.

Upvotes: 3

Views: 2976

Answers (4)

Steve S.
Steve S.

Reputation: 541

My use case is a little bit different, I'm using SAM and my Gateway is a HttpApi but I think it can apply to this scenario also.... so here's the entry you need to disable Auth on a specific API endpoint in your template:

  yourFunctionName:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/mycode.handler
      Description: Get some data
      FunctionName: getData
      Events:
        Api:
          Type: HttpApi
          Properties:
            ApiId: yourHttpApiGatewayRefHere
            Path: /data
            Method: GET
            Auth:
              Authorizer: NONE

The important section is

Auth: Authorizer: NONE

Upvotes: 0

AndersHA
AndersHA

Reputation: 101

Not sure if this directly answers the OP since we do not proxy our requests to a backend API but use Lambda for all API calls, but we still need to authorize only part of our API. This is how we've done it:

We have an API deployed with SAM and in this project we use a custom Authorizer for most of the api.

MonitorApi:
    Type: AWS::Serverless::Api
    Properties:
      Cors:
        AllowMethods: "'OPTIONS,POST,GET,PATCH,DELETE'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
      StageName: !Ref AppStage
      GatewayResponses:
        DEFAULT_4xx:
          ResponseParameters:
            Headers:
              Access-Control-Expose-Headers: "'*'"
              Access-Control-Allow-Headers: "'*'"
              Access-Control-Allow-Origin: "'*'"
      Auth:
        DefaultAuthorizer: LambdaTokenAuthorizer # This authorizer is used on the API
        AddDefaultAuthorizerToCorsPreflight: false
        Authorizers:
          LambdaTokenAuthorizer:
            FunctionArn: !GetAtt AuthorizeFunction.Arn
            Identity:
              Header: Authorization
              ReauthorizeEvery: 300

For some resources that we need to make publicly available we override this on the function level, like this:

  SystempingFunction: # Systemping service in API
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: monitor/
      Handler: systemping.handler
      Runtime: nodejs12.x
      Timeout: 20
      Events:
        SystempingEvent:
          Type: Api
          Properties:
            Auth:
              Authorizer: NONE # Turn off Authorization for this function
            Path: /systemping
            Method: get
            RestApiId: !Ref MonitorApi

Upvotes: 6

Sagar Jani
Sagar Jani

Reputation: 297

Finally, I have solved the issue the same way I described in my question,

As there is no way that AWS gives any programmatic way to omit a specific condition, we are left with below options :

  1. Create a separate API - In this way, AWS would give a preference to more specific API than a generic one i.e. API /server/ver1.0/rest/acc/reg would be given a preference to /server/ver1.0/rest/{proxy+} 2)

  2. Modify custom authorizer lambda function to check each and every URL pattern, but this makes lambda custom auth much complex and less maintainable.

I have adopted the first option as its more cleaner and easier to maintain, moreover I didn't want to pollute my lambda custom authorizer with various URL patterns

Upvotes: 4

mailtobash
mailtobash

Reputation: 2477

Assuming the custom authorizer is a lambda function, implying that your API Gateway is a proxy integration with Lambda - you could do it in the lambda function.

Depending on the resource you are requesting, eg : /acc/reg - you can detect this in the lambda function and bypass authentication. For all other resources you can go through the custom authorization process.

You could define variables to store your secure vs insecure resources, match those against the request

var insecureApis = '/hello,/acc/reg';
var secureApis = '/account/me';

var path = event.path;

if(secureApis.includes(path)){
    //perform custom auth and proxy request
} else {
   // just proxy
}

Upvotes: 2

Related Questions