documents/dev/snippets/aws/S3 midway authorizer.md
Table of Contents
S3 Midway Auth
- URL: https://d1qstwk8gomlqx.cloudfront.net/
- Test: https://d1qstwk8gomlqx.cloudfront.net/move.png
- MidwayActivate Lambda: https://chyut5ubfc.execute-api.us-east-1.amazonaws.com/default/midwayActivate
- Dynamo table: https://console.aws.amazon.com/dynamodb/home?region=us-east-1#tables:selected=auth;tab=items
- Harmony App: https://beta.console.harmony.a2z.com/activate/
- Repo: https://code.amazon.com/packages/Harmony-Midway-Activate
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;
}