Skip to main content

1. We have a community site. 

 2. There we have a page. 

 3. In that page, we have a link. 

 4. On click of that link a file opens up. the requirement is that only 'logged in user' should be able to open and see the file. 

 5. Nobody else should able to see it. 

 

More info using scenerio:- File should only opened with the help of click within the community site. After opening the file. If somebody copy the URL from address bar and then pasted in the 'incognito mode' then file should not be opened.  

 

Current progress:- 

 

I researched about and got solution related to pre-signed Url but i think it's the solution with help of code. I searching for any workaround using configuration within the AWS account.  

 

Any help would be appreciated. 

 

#Trailhead  #Experience Cloud  #Experience Site  #AWS S3  #AWS  #Lightning Aura Components  #Salesforce Developer  #Salesforce Admin

2 answers
  1. Sep 8, 4:22 PM

    Hi Kushagra, 

     

    An AWS-only configuration workaround won't work here, since S3 has no way of knowing whether a user is logged into your Salesforce community. Bucket policies and ACLs only understand AWS/IAM credentials, not Salesforce sessions. 

     

    The way to go is generating a pre-signed URL through Apex, right after checking that the user is logged in. This covers both your requirements: 

     

    - Only logged-in user can open the file -> Apex checks UserInfo.getUserId() before generating the URL 

    - Copy-pasted link shouldn't work later in incognito -> URL carries a short EXPIRY (in seconds); once it passes, AWS itself rejects the request 

     

    Sample Apex (server-side signing): 

     

    public with sharing class S3FileAccessController { 

     

        @AuraEnabled 

        public static String getSecureFileUrl(String fileKey) { 

     

            if (UserInfo.getUserId() == null) { 

                throw new AuraHandledException('User must be logged in to access this file.'); 

            } 

     

            String bucketName   = 'YOUR_BUCKET_NAME'; 

            String bucketRegion = 'YOUR_BUCKET_REGION'; // e.g. us-east-1 

            String accessKey    = 'YOUR_ACCESS_KEY';    // store in Named Credential / Custom Metadata 

            String secretKey    = 'YOUR_SECRET_KEY';    // store securely, never hardcode 

            Integer expiresInSeconds = 60; // short expiry blocks stale copy-pasted links 

     

            Datetime nowDT = Datetime.now(); 

            Long expiresEpoch = nowDT.addSeconds(expiresInSeconds).getTime() / 1000; 

     

            String stringToSign = 'GET\n\n\n' + expiresEpoch + '\n/' + bucketName + '/' + fileKey; 

     

            Blob mac = Crypto.generateMac('HMacSHA1', Blob.valueOf(stringToSign), Blob.valueOf(secretKey)); 

            String signature = EncodingUtil.urlEncode(EncodingUtil.base64Encode(mac), 'UTF-8'); 

     

            return 'https://' + bucketName + '.

    s3.amazonaws.com

    /' + fileKey 

                 + '?AWSAccessKeyId=' + accessKey 

                 + '&Expires=' + expiresEpoch 

                 + '&Signature=' + signature; 

        } 

     

    LWC — call this on file link click: 

     

    import { LightningElement } from 'lwc'; 

    import getSecureFileUrl from '@salesforce/apex/S3FileAccessController.getSecureFileUrl'; 

     

    export default class SecureFileLink extends LightningElement { 

        async handleFileClick() { 

            try { 

                const url = await getSecureFileUrl({ fileKey: 'path/to/file.pdf' }); 

                window.open(url, '_blank'); 

            } catch (e) { 

                console.error(e); 

            } 

        } 

     

    A few things to keep in mind: 

     

    - Never hardcode Access/Secret keys in Apex — use Named Credentials or Protected Custom Metadata Types instead 

    - Add an explicit sharing/permission check inside the Apex method, don't rely on link obscurity 

    - Keep expiresInSeconds low (30–60s) — this is what actually stops the "paste in incognito later" case, since AWS checks the Expires timestamp server-side 

    - Whitelist *.

    s3.amazonaws.com

    in Remote Site Settings if you're calling this through an Apex HTTP callout instead of pure signing 

     

    One thing worth flagging: if the same logged-in user copies the URL and pastes it in incognito within that expiry window, it will still open, since the URL itself carries the auth rather than the browser session. If you want to block even that, you'd need a proxy/streaming Apex REST endpoint that streams the file bytes back through Salesforce, checking the session on every single request, instead of redirecting straight to S3. Let me know if you want that pattern too. 

     

    Cheers!

0/9000