10

When I create classes, I've seen that there's an option to have create the class with or without sharing.

Example:

public class with sharing myClass{
    //  awesomeness
}

I've read the documentation, but what are the "sharing rules" enforced if I set my class to be with sharing? What's the extra benefit of having a class with (or without) sharing compared to classes without this specified?

I don't use sharing classes currently because (1) I'm uniformed and (2) I'm leary I will create code that won't work as I expect it. And I feel like I may be missing something useful by ignoring this functionality.


Update:

Right now, I don't use the with sharing property with my classes, and if a user's profile doesn't have ample field-level security settings, then the data isn't displayed. It seems that there already is security in place -- we use Sites extensively, and I have to manually give Site profiles permissions to view/use fields, objects, classes and pages. Is with sharing necessary? I don't use it now, and I still have to give permissions anyways, so what's the point? It seems to be a redundant security feature.

Are there any reasons why I should be using with sharing? Or my fears that I am doing things wrong unfounded?

  • 2
    I think you are missing the point of sharing. Salesman A can edit Opportunities. Salesman B can do the same. But in many cases they should not be able to edit (or even see) each others Opportunities. This is an example of why you would use a class "with sharing" – Doug B Sep 4 '13 at 18:17
  • Hmm I think I see what you mean. I'm usually concerned with my users having access to a whole Object rather than to a specific record. – Scott Pelak Sep 4 '13 at 18:42
16

To understand the implications to an apex class of with/without sharing first you need to understand how salesforce's security model works. It really consists of three layers of security:

  1. CRUD (Create,Read,Update,Delete), or table-level access. This is defined on the profile/permission set.
  2. FLS (Field level security), or column-level access. Also defined on profile/permission set.
  3. Sharing, or row-level access. This is much more complex and is based in large part on the configuration of your org.

CRUD is automatically enforced by standard controllers, if you make use of them. FLS is automatically enforced by the apex:inputField and apex:outputField tags, if you make use of them.

Sharing is enforced at the class level based on this keyword.

But what exactly is sharing?

It depends in large part upon you organization-level defaults. By default in new orgs most objects are set to public read/write, which disables sharing for that table until changed. This means that out of the box with/without sharing often won't have much an impact.

However once you do turn "on" sharing by changing this setting to something more restrictive you'll find that sharing is a complex calculation that's done by checking the role hierarchy, record ownership, apex-created sharing rules, point-and-click defined sharing rules, and even manual shares created by hand on a per-record basis.

The net effect of this is that sharing is much, much more complex to calculate than CRUD/FLS (which have simple apex methods for "can I do this?"), so this class-level control on sharing was introduced. If a class is defined as "with sharing" then the system will automatically enforce sharing on all queries you run, and DML you perform.

If your user only had read-level access to Account "X" and you try and update a field on it then "with sharing" would fail, but "without sharing" would succeed. The UI would fail in this scenario, and prevent the user from editing the record, so "with sharing" is a consistent experience for the user here.

If you leave off the sharing declaration then the class will inherit it's with/without sharing from whatever calls it. this is quite useful for helper classes with only static methods, if you leave off the sharing declaration then whatever calls these methods will determine if they respect sharing or not. If a class with no sharing declared is the top-level in a request (e.g. a visualforce page controller) then it will default to acting "without sharing".

Edit: Except when using execute anonymous, where it will behave as "with sharing".

  • 2
    ... unless you're using Execute Anonymous or using Chatter, in which case it acts "with sharing." – sfdcfox Sep 4 '13 at 21:54
  • ok, now I'm curious - how can chatter be an entry point to non-trigger apex? – ca_peterson Sep 4 '13 at 23:08
  • 1
    Chatter in Apex The ConnectApi calls use "with sharing", if I understand this correctly. – sfdcfox Sep 5 '13 at 0:59
  • The whole chatter in apex is... odd. It's incapable of running in system mode at all, which is why I left it out of this answer - since your class declaration doesn't impact it anyways. – ca_peterson Sep 5 '13 at 1:53
3

In fact, the without sharing allow you to see all data even if records are private for exemple.

If the Sharing Settings of Account object is set to private for exemple, using the "With sharing" will limit the SOQL query to only accounts owned by the user ; while the "without sharing" allow you to query all the accounts. By default, if you don't specify anything, the behavior is "without".

  • 1
    Instead of being the owner, a user can also gain access in a private sharing model by having the record shared with them (see sharing button on detail page). It's also important to mention that any class annotated without sharing is considered a security failure in the force.com security scanner. – Phil Rymek Sep 3 '13 at 16:06
  • If you don't specify anything then the default behaviour isn't "without". It is to take on the behaviour from the calling class. So, for example, you can write a helper class of database queries and not specify "with" or "without" sharing. Then if the methods in that helper class are called from a controller which is "with sharing" those helper methods will execute "with sharing". If the same helper class methods are called from a controller which is "without sharing" they will execute "without sharing". – Doug B Sep 4 '13 at 6:47
  • Yes, sharing is enforced if a class call another. In my response i was thinking of a trigger calling the class, sorry – Yann Gorvel Sep 4 '13 at 6:50
3

It affects whether the code in the class will respect the sharing rules on record access. "With sharing" means that queries executed are limited to the rows shared to the user. "Without sharing" means that sharing rules are not enforced in the query results.

If a class is not declared as either with or without sharing, the current sharing rules remain in effect. This means that if the class is called by a class that has sharing enforced, then sharing is enforced for the called class.

You should really read http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_keywords_sharing.htm

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.