CloudFront and S3 with "user-agent" condition

Viewed 16

, i have setup CF distro with S3 as an origin but i want to make a condition before i serve the content The condition i want it to make sure the request have "user-agent": "example" inside , if she has ONLY then serve the content and if not block it. for now i succeeded to make it work with a S3 bucket policy with condition but the problem is when the content is cached and try to hit the url without the condition it still serve me the website.

how can i implement this solution? i have tried to use lambda@edge on "Viewer request" event but i get 503 error that my lambda dont have enough permissions (with "Origin Request" it worked fine)

bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipalReadOnly",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket-name>/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::account-number:distribution/EXAMPLEDISTO"
                },
                "StringLike": {
                    "AWS:UserAgent": "*STRING*"
                }
            }
        }
    ]
}
1 Answers

i post my answer for anyone who need it :

i removed the condition of :

        "StringLike": {
            "AWS:UserAgent": "*STRING*"
        }

and my lambda function (pyhton)looks like:

def handler(event, context):

    request = event['Records'][0]['cf']['request']
    headers = request['headers']
    
    user_agent = headers.get('user-agent')
    custom_agent = 'EXAMPLE_STRING'
    url = 'https://DSADSACDXVDV.cloudfront.net/error.html/'
    url_2 = 'https://yourdomain.com'
    
    if custom_agent not in user_agent[0]['value']:
      response = {
        'status': '404',
        'statusDescription': 'NotFound',
        'headers': {
            'location': [{
                'key': 'Location',
                'value': url
            }]
        }
    }
      return response
    else:
      response = {
        'status': '302',
        'statusDescription': 'Found',
        'headers': {
            'location': [{
                'key': 'Location',
                'value': 'https://yourdomain.com/'
            }]
        }
    }
        
    return request
    

now requests that dont have the required user-agent like in lambda code get rejected.

Related