7

I had a question with regards to custom authorization for AWS API Gateway using a lambda coded in C#. In the documentation for AWS Lambdas, the function signature is as follows:

returnType handler-name(inputType input, ILambdaContext context) {
   ...
}

The inputType and returnType need to be specified for the function handler. For custom authorization in API Gateway, what should the inputType and returnTypes be? Thanks in advance.

4 Answers 4

12

You can opt for a strongly-typed approach without inventing custom classes that need to follow the required schema.

Use Nuget package:

Amazon.Lambda.APIGatewayEvents

Input schema:

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

Output schema:

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

Your function prototype can then resemble:

using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;

public class Function
{
    public APIGatewayCustomAuthorizerResponse FunctionHandler(APIGatewayCustomAuthorizerRequest input, ILambdaContext context)
    {
        bool ok = false;
        // authorization logic here...
        if(input.AuthorizationToken == "up-down-left-right-a-b-select-start")
        {
            ok = true;
        }
        return new APIGatewayCustomAuthorizerResponse
        {
            PrincipalID = "***",//principal info here...
            UsageIdentifierKey = "***",//usage identifier here (optional)
            PolicyDocument = new APIGatewayCustomAuthorizerPolicy
            {
                Version = "2012-10-17",
                Statement = new List<APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement>() {
                      new APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement
                      {
                           Action = new HashSet<string>(){"execute-api:Invoke"},
                           Effect = ok ? "Allow" : "Deny",
                           Resource = new HashSet<string>(){  "***" } // resource arn here
                      }
                },
            }
        };
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Since the resources section is a List, would you add all the resources the particular user has access to?
Tried to edit the response, but "too many pending edits", so, lest I forget: For the 2.0 Payload format version, you would return a APIGatewayCustomAuthorizerV2SimpleResponse response like { "isAuthorized": true/false, "context": { "exampleKey": "exampleValue" }}, and the corresponding APIGatewayCustomAuthorizerV2Request as your firstFunctionHandler parameter.
2

I thought I would elaborate this a bit. This uses part of what was done here as well as tried to make it like the example they give us here. http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html

I am not sure if it needs to be async or not? I didn't and this seemed to work pretty well for a basic start.

public class Authorize
{
    public Authorize() { }

    public AuthPolicy AuthorizeHandler(TokenAuthorizerContext request, ILambdaContext context)
    {
        var token = request.AuthorizationToken;

        switch (token.ToLower())
        {
            case "allow":
                return generatePolicy("user", "Allow", request.MethodArn);
        }

        return null;
    }

    private AuthPolicy generatePolicy(string principalId, string effect, string resource)
    {

        AuthPolicy authResponse = new AuthPolicy();
        authResponse.policyDocument = new PolicyDocument();
        authResponse.policyDocument.Version = "2012-10-17";// default version
        authResponse.policyDocument.Statement = new Statement[1];

        Statement statementOne = new Statement();
        statementOne.Action = "execute-api:Invoke"; // default action
        statementOne.Effect = effect;
        statementOne.Resource = resource;

        authResponse.policyDocument.Statement[0] = statementOne;

        return authResponse;
    }

}
public class TokenAuthorizerContext
{
    public string Type { get; set; }
    public string AuthorizationToken { get; set; }
    public string MethodArn { get; set; }
}

public class AuthPolicy
{
    public PolicyDocument policyDocument { get; set; }
    public string principalId { get; set; }
}

public class PolicyDocument
{
    public string Version { get; set; }
    public Statement[] Statement { get; set; }
}

public class Statement
{
    public string Action { get; set; }
    public string Effect { get; set; }
    public string Resource { get; set; }
}

Comments

1

I wanted to post the solution that I used that worked for me. Thanks to Josh Maag for pointing me in the right direction. Basically, I created a few simple classes:

public class TokenAuthorizerContext
{
    public string Type { get; set; }
    public string AuthorizationToken { get; set; }
    public string MethodArn { get; set; }
}

public class AuthPolicy
{
    public PolicyDocument policyDocument { get; set; }
    public string principalId { get; set; }
}

public class PolicyDocument
{
    public string Version { get; set; }
    public Statement[] Statement { get; set; }
}

public class Statement
{
    public string Action { get; set; }
    public string Effect { get; set; }
    public string Resource { get; set; }
}

```

With the above classes created, the signature to my handler is:

public async Task<AuthPolicy> FunctionHandler(TokenAuthorizerContext request, ILambdaContext context)

1 Comment

Have a look at the nuget package Amazon.Lambda.APIGatewayEvents I've also posted an example below.
0

You should really take a look at the following link and try to follow it through. The full tutorial is written using Python, so if you're unfamiliar with it, just do your best to follow along and read the full walk-through, but this link will explain the C# portion:

http://docs.aws.amazon.com/lambda/latest/dg/get-started-step5-optional.html

Essentially, the string:

returnType handler-name(inputType input, ILambdaContext context) {

Would be something like this (copied from the AWS page):

public string MyHandler(int count, ILambdaContext context) { ... }

public is added as a scope modifier, the returnType the developer has chosen is string the handler-name is MyHandler and the inputType is int

2 Comments

This question is specific to custom authorization in API Gateway using a Lambda. I have no control over the input because the API Gateway provides the input and therefore I don't know the input type it provides or the return type it expects.
I think it is the same. For an example, look at the aswlabs Java implementation which has some similarities to C#. github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/… If you look at example/APIGatewayAuthorizerHandler.java, you can see they have: `public AuthPolicy handleRequest(TokenAuthorizerContext input, Context context) { .. }'

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.