5

My objective is to protect an aws s3 bucket link and I'm trying to solve this by using cloudfront as the link via which the s3 buckets are accessible, hence when a user tries to access the cloudfront link, there is a basic auth if there's no cookie in their browser, but if there's a cookie, then auth values in this cookie is checked and user is granted access. PS: This is not a website, my quest is to protect s3 bucket links.

Here is my attempt, using lambda@edge, on viewer request, there's the auth page if user is not logged in, otherwise, they're allowed access, it works but I can't set cookies, because somewhere in aws documentation, cloudfront deletes set-cookies in header files: CloudFront removes the Cookie header from requests that it forwards to your origin and removes the Set-Cookie header from responses that it returns to your viewers

Here is my code:

'use strict';

// returns a response error
const responseError = {
                status: '401',
                statusDescription: 'Unauthorized',
                headers: {
                    'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
                }
};




exports.handler = (event, context, callback) => {
    // Get request and request headers
    console.log(event.Records[0]);
    const request = event.Records[0].cf.request;
    const response = event.Records[0].cf.response;
    const headers = request.headers;



    // checks to see if headers exists with cookies
    let hasTheHeader = (request, headerKey) => {
        if (request.headers[headerKey]) {
            return true;
        } 
        else return false;
    };

    // Add set-cookie header to origin response
    const setCookie = function(response, cookie) {
        const cookieValue = `${cookie}`;
        console.log(`Setting cookie ${cookieValue}`);
        response.headers['set-cookie'] = [{ key: "Set-Cookie", value: cookieValue }];    
    }


    // Configure authentication
    const authUser = 'someuser';
    const authPass = 'testpassword';
    let authToken;
    let authString;

    // Construct the Auth string
    const buff = new Buffer(authUser + ':' + authPass).toString('base64');
    authString = 'Basic ' + buff;


    const authCookie = 'testAuthToken';

    //execute this on viewer request that is if request type is viewer request:
    if(event.Records[0].cf.config.eventType == 'viewer-request'){

        //check if cookies exists and assign authToken if it does not
        if(hasTheHeader(request, 'cookie')  ){
            for (let i = 0; i < headers.cookie.length; i++)
            {
                if (headers.cookie[i].value.indexOf(authString) >= 0)
                {
                    authToken = authString;
                    console.log(authToken);
                    break;
                }
            }
        }

        if (!authToken)
        {
                if (headers && headers.authorization && headers.authorization[0].value === authString)
                    {

                        // Set-Cookie: testAuthToken= new Buffer(authUser + ':' + authPass).toString('base64')



                        authToken = authString;
                        request.header.cookie = [];

                        //put  cookie value to custom header - format is important
                        request.headers.cookie.push({'key': 'Cookie', 'value': authString});

                    }
                else
                    {
                        callback(null, responseError);
                    }

                // continue forwarding request
                callback(null, request);
        }

        else{
            //strip out "Basic " to extract Basic credential in base 64
            var authInfo = authToken.slice(6);    

            var userCredentials = new Buffer(authInfo, 'base64');
            var userLoginNamePass = userCredentials.toString();

            var baseCredentials = userLoginNamePass.split(":");
            var username = baseCredentials[0];
            var userPass = baseCredentials[1];


            if (username != authUser && userPass != authPass) {

                //user auth failed
                callback(null, responseError);

            } else {

                request.header.cookie = [];

                //put  cookie value to custom header - format is important
                request.headers.cookie.push({'key': 'Cookie', 'value': authString});

            }

            // continue forwarding request
            callback(null, request);

        }

    }
    else if(event.Records[0].cf.config.eventType == 'origin-response')
    {

        if(hasTheHeader(request, 'cookie')){
            for (let i = 0; i < headers.cookie.length; i++)
            {
                if (headers.cookie[i].value.indexOf(authString) >= 0)
                {
                    setCookie(response, authString);
                    break;
                }
            }

        }

        // console.log(res_headers);
        console.log("response: " + JSON.stringify(response));
        callback(null, response);

    }
};

Your suggestions will be most welcome. Thanks in advance.

Amaz Triss
  • 96
  • 7

0 Answers0