documents/dev/snippets/aws/S3 midway authorizer.md

S3 Midway Auth

Midway Activate

Decode auth

headers.authorization[0].value === 'Basic ' + new Buffer(user + ':' + pw).toString('base64');

To decode...

const AWS = require('aws-sdk');

let ddb;
const getAuth = async(user) => {
    if (!ddb) {
        ddb = new AWS.DynamoDB.DocumentClient({
            apiVersion: '2012-08-10',
            region: 'us-east-1',
            sslEnabled: false,
            paramValidation: false,
            convertResponseTypes: false
        });
    }
    try {
        const entry = await ddb.get({
            TableName: 'auth',
            Key: { "user": user }
        }).promise();
        return entry.Item;
    }
    catch (e) {
        return null;
    }
};

exports.handler = async(event, context) => {

    // unauth response
    let response = {
        status: '401',
        statusDescription: 'Unauthorized',
        body: 'Unauthorized',
        headers: {
            'www-authenticate': [{ key: 'WWW-Authenticate', value: 'Basic' }]
        },
    };

    // Get the request and its headers
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    // Challenge for auth if auth credentials are absent
    if (typeof headers.authorization === 'undefined') return response;

    // decode auth key, check against db
    const encodedStr = headers.authorization[0].value.substr(6);
    const buffer = new Buffer(encodedStr, 'base64');
    const decoded = buffer.toString('ascii').split(':');
    const login = decoded[0];
    const password = decoded[1];
    const entry = await getAuth(login);

    const isAuthSuccessful = (entry && entry.pw === password);
    if (!isAuthSuccessful) return response;
    return request;
};

Sample Response

exports.handler = async (event, context) => {
    const response = {
        status: '200',
        statusDescription: 'OK',
        headers: {
            vary: [{
                key: 'Vary',
                value: '*',
            }],
            'last-modified': [{
                key: 'Last-Modified',
                value: '2017-01-13',
            }],
        },
        body: 'Example body generated by Lambda@Edge function.',
    };
    return response;
};

Change Request URI

See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html

exports.handler = async (event, context) => {
    const request = event.Records[0].cf.request;

    const cookieExperimentA = 'X-Experiment-Name=A';
    const cookieExperimentB = 'X-Experiment-Name=B';
    const pathExperimentA = '/experiment-group/control-pixel.jpg';
    const pathExperimentB = '/experiment-group/treatment-pixel.jpg';
	    if (!experimentUri) {
        console.log('Experiment cookie has not been found. Throwing dice...');
        if (Math.random() < 0.75) {
            experimentUri = pathExperimentA;
        } else {
            experimentUri = pathExperimentB;
        }
    }

    request.uri = experimentUri;
	return request;
}