简体   繁体   中英

AWS API Gateway ignores auth policy returned from the Custom Authorizer Lambda Function

I'm trying to implement custom authorization on API Gateway, that would check user's permissions on each particular endpoint behind it, by reading them from the DynamoDB.

I associated the authorizer with the method in question (screenshot below) 在此处输入图像描述

The authorizer seems to be working ok, and it returns policy that looks fine to me (have a look underneath)

{
    "policyDocument" : {
        "Version" : "2012-10-17",
        "Statement" : [
            {
                "Action" : "execute-api:Invoke",
                "Effect" : "Deny",
                "Resource" : "arn:aws:execute-api:us-east-2:111111111111:mkvhd2q179/*/GET/api/Test"
            }
        ]
    },
    "principalId"    : "*"
}

However, regardless of the Effect authorizer returned inside the policy document, API Gateway still let's all requests pass. I get the status 200 as well as the result set from the API endpoint underneath.

Any ideas as to why the API Gateway would ignore the policy?

PS I tried with the explicit principalID (the username/subject from the token) prior to putting an asterisk there. It behaved the same.

PPS Here's completely dummed down version of my Lambda function, currently set up to allways return Deny as policy Effect...

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

        var stream = token;
        var handler = new JwtSecurityTokenHandler();
        var jsonToken = handler.ReadToken(stream);
        var tokenS = handler.ReadToken(token) as JwtSecurityToken;

        return generatePolicy(tokenS.Subject, "Deny", "arn:aws:execute-api:us-east-2:111111111111:mkvhd2q179/*");
    }

    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];
        authResponse.principalId = "*";

        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; }
}

TL;DR; Remove/change/check the "Resource Policy" set in the Gateway.

I had a similar problem. Somehow I had a "allow * principal access to * resources" policy set in the Resource Policy on the Gateway which was being combined with whatever the Authorizer was returning. I ended up removing all resource policies and let the Authorizer decide.

I had this problem as well. Turns out that making the request from the API Gateway console screen (eg https://us-west-2.console.aws.amazon.com/apigateway/ ) doesn't appropriately invoke the authorizer.

I'm guessing its because your console session has its own IAM policy, which interferes with the authorizer policy.

The solution was to manually CURL the endpoint outside of the API Gateway console.

Additionally, do not forget to deploy your API after you make your changes: Otherwise your changes won't be taking effect:

在此处输入图像描述

I had a similar issue. The way our API gateway resource policy was set up to allow us to execute any API in the account level ( arn:aws:execute-api:us-east-1:xxxxx:* ).

Even though implemented fine-grained access where we return a policy to allow only particular arn the API gateway resource policy was taking precedence. So I have removed the resource policy and redeployed the API and it was allowing that particular API and denying the others. OR u can try vice versa based on how you configure your Effect and policy statement.

Initial Resource Policy: (I removed and redeployed)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:xxxxx:*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "xx.xx.xx.xxx/24"
                    ]
                }
            }
        }
    ]
}

Final Lambda Auth Policy returned:

 {
    "principalId": "xxxxxxxxxx",
    "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "execute-api:Invoke"
                ],
                "Resource": [
                    "arn:aws:execute-api:us-east-1:xxxxx:bxxxx/*/POST/*/someresource"
                ]
            }
        ]
    }
}

The AWS Documentation is confusing... it seems that you still need to use the "callback" to do the trick and is not enough to return an "Deny" policy...

exports.authorizer = (event, context, callback) => {

  if (invalidToken) {
    callback("Unauthorized", null);
  }

  // create a valid policy

  return validPolicy
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM