Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# implementation of AWS API Gateway Custom Authorization Lambda

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.

like image 766
user2689570 Avatar asked Jan 03 '17 20:01

user2689570


2 Answers

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
                      }
                },
            }
        };
    }
}
like image 140
Aaron Hudon Avatar answered Sep 19 '22 02:09

Aaron Hudon


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; }
}
like image 22
Kalel Wade Avatar answered Sep 21 '22 02:09

Kalel Wade