1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Java Lambda で API Gateway の Lambda Authorizer を実装する

Last updated at Posted at 2020-10-01

API Gateway(Rest API) の Lambda Authorizer では、Lambda のレスポンスに 指定の JSON を返す 必要があります。

Lambda Authorizer って何?って方は こちら を。

Node.js だと、こんな感じで、そのまま JSON を返せます。便利ですね。

exports.handler = async (event) => {
  console.log(JSON.stringify(event, null, 4));
  return {
    "principalId": "1234",
    "policyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": "execute-api:Invoke",
          "Effect": "Allow",
          "Resource": event.methodArn
        }
      ]
    }
  };
};

Java の場合は、JSON では返せないですし、JSON を文字列として返してもうまくいきません。
方法としては 2 つあって、Map を使う方法と POJO クラスを使う方法です。

Map を使う方法

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class MapLambdaAuthorizer implements RequestHandler<Map<String, Object>, Map<String, Object>> {
    @Override
    public Map<String, Object> handleRequest(Map<String, Object> event, Context lambdaContext) {
        Map<String, Object> response = new HashMap<String, Object>();
        response.put("principalId", "1234");

        Map<String, Object> policyDocument = new HashMap<String, Object>();
        policyDocument.put("Version", "2012-10-17");

        Map<String, String> statement = new HashMap<>();
        statement.put("Action", "execute-api:Invoke");
        statement.put("Effect", "Allow");
        statement.put("Resource", (String) event.get("methodArn"));
        policyDocument.put("Statement", Arrays.asList(statement));

        response.put("policyDocument", policyDocument);

        Map<String, String> context = new HashMap<String, String>();
        context.put("now", new Date().toString());
        response.put("context", context);

        return response;
    }
}

POJO を使う方法

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class PojoLambdaAuthorizer implements RequestHandler<Map<String, Object>, AuthorizerResponse> {
    @Override
    public AuthorizerResponse handleRequest(Map<String, Object> event, Context lambdaContext) {
        AuthorizerResponse response = new AuthorizerResponse();
        response.setPrincipalId("1234");

        Map<String, Object> policyDocument = new HashMap<>();
        policyDocument.put("Version", "2012-10-17");

        Map<String, String> statement = new HashMap<>();
        statement.put("Action", "execute-api:Invoke");
        statement.put("Effect", "Allow");
        statement.put("Resource", (String) event.get("methodArn"));
        policyDocument.put("Statement", Arrays.asList(statement));

        response.setPolicyDocument(policyDocument);

        Map<String, String> context = new HashMap<>();
        context.put("now", new Date().toString());
        response.setContext(context);

        return response;
    }
}

import java.util.Map;

public class AuthorizerResponse {
    private String principalId;

    public void setPrincipalId(String principalId) {
        this.principalId = principalId;
    }

    public String getPrincipalId() {
        return this.principalId;
    }

    private Map<String, Object> policyDocument;

    public void setPolicyDocument(Map<String, Object> policyDocument) {
        this.policyDocument = policyDocument;
    }

    public Map<String, Object> getPolicyDocument() {
        return this.policyDocument;
    }

    private Map<String, String> context;

    public Map<String, String> getContext() {
        return context;
    }

    public void setContext(Map<String, String> context) {
        this.context = context;
    }
}

POJO にするなら、

policyDocument.put("Version", "2012-10-17");
statement.put("Action", "execute-api:Invoke");

とかも POJO にしないと気持ち悪いところですが、POJO にした場合に API Gateway に返される JSON のキー名が小文字始まり(version、action)になってしまい、うまく解釈してくれませんでした。

まとめ

JSON がそんなに大きくないので、Map 方式の方が読みやすくていいと思います。

Source Code

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?