I have a Site, where external, unauthenticated users can access some of the files we store in Salesforce. To achieve this, I use Content Distribution records, to obtain the public URLs for these files. The Visualforce page displayed in the Site has a controller, which queries related
ContentDistributionrecords and displays the links. This was working fine up until a few days ago (possibly up until the Winter’19 release).
Currently when external users try to access the files, the controller throws an error:
sObject type 'ContentDistribution' is not supported
As a workaround I moved querying
without sharingclass and use a Custom wrapper class to hold the name and URL of the file, but this doesn’t seem like a good solution in the long term.
Is there any new feature or critical update, that I missed, that takes away access to
ContentDistributionfrom public Site users? And if so, is there any better way to allow unauthenticated users see/download files from a Salesforce org?
I know about the “share via link” option on files – but I haven’t found any resources on how to use it programmatically (both to create the public link and to query it).
The answer is to use a without sharing class that does access control and only delivers the data the current guest user is allowed to access. You should not be granting declarative access to objects to guest users as there is no way to distinguish them. In your controller, you can distinguish them.
In general when you have guest users your controllers will need to be without sharing. Of course this requires you to be very careful in implementing your own procedural access control logic, but that’s better than granting blanket access to anonymous internet users to read your organization’s data. For example if you have a without sharing controller you can do things like use secure tokens in cookies, rely on a third party service to identify the user, and require captchas. A combination of these techniques can allow you to add your own access control logic when dealing with guest users and only serve data to them which they are allowed to see. But if you mark an object as accessible to the guest user, then they can use standard controllers to access that object at any time, and your code will not be able to deny them access.
For additional examples of using the above patterns in without sharing controllers to give controlled access to guest users, look at this blog post: https://www.learnexperiencecloud.com/s/article/Guest-User-Record-Access-Development-Best-Practices