Skip to content

Instantly share code, notes, and snippets.

@apoorvmote
Created March 2, 2021 11:57
Show Gist options
  • Save apoorvmote/1a4b2de1770b6e8e78ce8304cef84a9c to your computer and use it in GitHub Desktop.
Save apoorvmote/1a4b2de1770b6e8e78ce8304cef84a9c to your computer and use it in GitHub Desktop.
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request
const headers = request.headers
const user = 'my-username'
const password = 'my-password'
const authString = 'Basic ' + Buffer.from(user + ':' + password).toString('base64')
if (typeof headers.authorization === 'undefined' || headers.authorization[0].value !== authString) {
const response = {
status: '401',
statusDescription: 'Unauthorized',
body: 'Unauthorized',
headers: {
'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
}
}
callback(null, response)
}
callback(null, request)
}
///////////////////////////////
// Part 1
const hostedZone = HostedZone.fromHostedZoneAttributes(this, 'HostedZoneWithAttr', {
hostedZoneId: hostedZoneId,
zoneName: website_domain
})
const previewCert = new DnsValidatedCertificate(this, 'previewSSL', {
domainName: preview_domain,
hostedZone
})
const previewBucket = new Bucket(this, 'previewBucket', {
removalPolicy: RemovalPolicy.DESTROY,
bucketName: preview_domain,
autoDeleteObjects: true,
websiteIndexDocument: 'index.html',
websiteErrorDocument: '404.html'
})
new CfnOutput(this, 'previewBucketWebsiteUrl', {
value: previewBucket.bucketWebsiteUrl
})
///////////////////////////////
///////////////////////////////
// Part 2
previewBucket.addToResourcePolicy(new PolicyStatement({
sid: 'allow request from cloudfront to s3 website',
effect: Effect.ALLOW,
principals: [new AnyPrincipal()],
actions: ['s3:GetObject'],
resources: [`${previewBucket.bucketArn}/*`],
conditions: {
"StringLike": {
"aws:Referer": [previewSecret]
}
}
}))
const previewCachePolicy = new CachePolicy(this, 'previewCachePolicy', {
defaultTtl: Duration.minutes(30),
minTtl: Duration.minutes(25),
maxTtl: Duration.minutes(35),
enableAcceptEncodingBrotli: true,
enableAcceptEncodingGzip: true,
headerBehavior: CacheHeaderBehavior.allowList('authorization')
})
const edgeAuth = new experimental.EdgeFunction(this, 'edgeAuthFn', {
runtime: Runtime.NODEJS_12_X,
handler: 'index.handler',
code: Code.fromAsset(`${__dirname}/../lambda-fns/basic-auth/deployment.zip`),
memorySize: 128
})
///////////////////////////////
///////////////////////////////
// Part 3
const previewDistribution = new Distribution(this, 'previewDistribution', {
defaultBehavior: {
origin: new HttpOrigin(previewBucketWebsiteUrl, {
protocolPolicy: OriginProtocolPolicy.HTTP_ONLY,
customHeaders: {
'Referer': previewSecret
}
}),
edgeLambdas: [{
functionVersion: edgeAuth.currentVersion,
eventType: LambdaEdgeEventType.VIEWER_REQUEST
}],
allowedMethods: AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
cachePolicy: previewCachePolicy,
compress: true,
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS
},
domainNames: [preview_domain],
certificate: previewCert,
minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_2_2019,
httpVersion: HttpVersion.HTTP2,
priceClass: PriceClass.PRICE_CLASS_ALL
})
///////////////////////////////
///////////////////////////////
// Part 4
new ARecord(this, 'aliasForPreview', {
target: RecordTarget.fromAlias(new CloudFrontTarget(previewDistribution)),
zone: hostedZone,
recordName: preview_domain
})
///////////////////////////////
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment