Shared Components with Lambda Layers

Now that we have a second microservice that will be moving into our architecture, we need to start thinking about how we can move common mechanisms that have tenant-context to reusable components. We could certainly user libraries and frameworks to do this. The question is, how do we make the reusable across our services. This is where Lambda layers come in. With layers, we can separately deploy and version shared code that will support our need to hide away the details of multi-tenancy. So, before moving over our Product service, let’s start by creating these shared constructs.

Let’s start with the token manager class. The role of the token manager is to simplify acquiring the tenant identifier from the supplied JWT token. This class is a shared by the other classes in the layer to acquire a tenant identifier. The code for this class is shown below.

package com.amazon.aws.partners.saasfactory;

import com.amazonaws.services.lambda.runtime.Context;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.UUID;

public class TokenManager {

    private static final Logger LOG = LoggerFactory.getLogger(TokenManager.class);
    private static final String SIGNING_KEY = "+Kahb1I+prVQZF41dRpNj22qBtAw4Qn1P45VwpELXCc=";

    public static String getTenantId(Map<String, Object> event) {
        return getTenantId(event, null);
    }

    public static String getTenantId(Map<String, Object> event, Context lambdaContext) {
        String bearerToken = ((Map<String, String>)
                event.get("headers")).get("Authorization");
        String jwtToken = bearerToken.substring(bearerToken.indexOf(" ") + 1);
        Claims verifiedClaims = Jwts.parser()
                .setSigningKey(SIGNING_KEY)
                .parseClaimsJws(jwtToken)
                .getBody();
        String tenantId = verifiedClaims.get("TenantId", String.class);
        return tenantId;
    }
}

The token manager has two overloaded functions that both get a tenant identifier. The key piece of code here (shown on lines XX-XX) extract the bearer token from the header and unpacks the signed token using a key. Finally, once the token is unpacked, we get the “TenantId“ from the claims and returns this value.

To add this file to a layer, first navigate to the Cloud9 service in the AWS console and open the environment for this work. Next, select the “Lab 4/layers/token-manager“ folder in the navigation tree on the left. Right click on the folder and select “New file“. The will add an entry to the folder. Type the file name “token-manager.java“ into the placeholder in the source tree the code above into this new file and save it as “token-manager.java“ and press enter. Once the file has been created, double-click on the newly added file to open the empty file editor on in the right-hand pane. Now, paste the contents above into the editor and select “File | Save“ from the menu at the top left of the IDE.