89

Per my understanding of With Sharing, Without Sharing and non-sharing-specified Classes in Apex, I would like to jot down the following notes and leave certain blanks for not sure answers; I wanted to know if I were correct/not and clear/not with the following notes.

1) With Sharing keyword implies in another words, "with Security Settings enforced". This again, pertains to only respecting OWDs and Sharing Rules [ What about Object Level Security/OLS and Field Level Security/FLS? ]

2) If a class is declared as "with sharing" then, the sharing settings apply to all code contained in the class, including initialization code, constructors and methods. However, Inner Classes DO NOT inherit sharing settings from the container class.

3) If a class is not declared either with sharing or without sharing, then by default, such a class is executed in system mode, i.e. without sharing mode; and current sharing rules remain in effect- which means that if any other class that has sharing enforced, calls such a non-specified-sharing class, then the called or non-specified-sharing class is executed in "with sharing" mode.

4) If class B extends class A, then all code in class B inherits the same sharing settings that class A has. However, class B's inner classes do not inherit class B's sharing settings.

5) If a with sharing class calls a without sharing class, then the called method(s) will be executed in the mode of the class in which they were defined, in this case, the called method(s) will execute in without sharing mode.

I have written a few example case scenarios, as below, that would summarize the understanding of the above concepts, I would like to learn if I am correct, also willing to know expert advice / suggestions w.r.t each of the below scenarios.

Say I have 3 classes:

  • public with sharing class A {}
  • public without sharing class B{}
  • public class C{} // Class C is a non-specified-sharing class.

Now, let's consider the following case scenarios:

  1. class B extends A // class B's code now executes in class A's mode, i.e. in "with sharing" mode.

  2. class B calls class A // called code will now be executed in the mode of the class in which it was defined, in this case, in class A's mode, i.e. in "with sharing" mode.

  3. class C calls class A // called method's code in class A will execute in class A's mode, i.e. in "with sharing" mode.

  4. class C extends class A // code in class C now executes in the parent class A's mode, i.e. in "with sharing" mode.

  5. class A calls C // code in class C is executed in class C's mode, i.e. in "without sharing" mode although it's sharing settings are unspecified in the class' declaration.

  6. class A extends C // class A's code now executes in the parent class C's mode, i.e. in "without sharing" mode.

I'm not quite sure of the case 6. Besides, I also wanted to know the use cases for which the with sharing and without sharing rules are applied and used. How are the sharing settings applicable in case of Visualforce Controller Classes and/or Controller Extensions.

1
  • This seems pretty academic and theoretical [which is OK] - but is there a real life problem you're trying to solve, or is this just about exploring the intricacies of Apex?
    – Benj
    Commented Sep 2, 2013 at 0:56

4 Answers 4

73

Part 1

  1. Correct. You cannot "automatically" enforce field level security or profile permissions with "with sharing," as this would make code much more difficult to debug because of failures. This is noted in Using the with sharing or without sharing Keywords, under the second note.

  2. Correct. This means that if do not specify "with sharing" or "without sharing" for the inner class, it behaves according to the calling class mode, or "without sharing" if called directly, except as noted in the first section of the link provided above.

  3. Partially correct. If you run a class that has no sharing in Execute Anonymous, or in Chatter, it is treated as "with sharing." In all other cases, it is treated as "without sharing." For most cases, this is not significant, but you should be aware of this feature.

  4. Correct. Extensions are basically a rewrite of the original class plus additional code, so they behave like the original class, including its sharing mode.

  5. Correct. Calling a function in a class will use the sharing mode of that class, unless it is undefined, in which case the mode stays the same.

Part 2

  1. Correct, as per 4 above.

  2. Correct, as per 5 above.

  3. Correct, as per 5 above.

  4. Correct, as per 4 above.

  5. Incorrect, as per 3 above. Because A has "with sharing", C will have "with sharing" when called from A.

  6. Partially correct, or incorrect, depending on the exact definition of A. If A is "public with sharing class A extends C", then it is "with sharing," or if it is "public class A extends C", then it falls under item 3 from part 1 (that is, "without sharing unless executed from executeAnonymous").

With Sharing

This is when you're trying to perform an update as the user. If user X cannot edit record Y, then an error will occur. If user X cannot see record Y, they cannot query that record. Use this mode when for pages that should respect sharing settings, or any other time you might want to enforce the rules.

For example, a page that edits opportunities should probably enforce sharing to make sure that users can't modify other users' sales data without the appropriate sharing in place. For Visualforce pages, this is true approximately 99% of the time. Some Visualforce pages might be able to circumvent sharing, for example, to show data that the user wouldn't normally. A page that can tell users that a possible duplicate lead exists (without exposing who works the lead, or specific details) would not want to use "with sharing" in a private data model.

Without Sharing

This is when you're trying to perform an update that should not fail ordinarily. For example, a logging system is designed to write certain non-fatal messages to a logging object. The user doesn't have any right to edit the logging files normally (OWD is private, and the logging records are owned by a system administrator), but the logging files need to be queried and updated accordingly (to save space, etc). Using "with sharing" would make this code impossible, but by placing that code in a "without sharing" class, the code can make logs on behalf of the user even though that user has no access to the object normally. As another example, users can't see others leads, but the system needs to flag potential duplicates and notify someone that there is a duplicate. "Without sharing" makes this code possible.

6
  • 4
    This question & answer are extremely helpful for the updated platform dev certifications. Reading this answer made me realize that I misunderstood a lot of the Apex privacy fundamentals. Commented Oct 9, 2015 at 14:29
  • 1
    Inherited sharing works differently than excluding a sharing modifier altogether in terms of extending a parent class and how it affects sharing. "public class ChildClass extends ParentClass" will take on the sharing context of its parent class instead of the class calling a method in ChildClass. However "public inherited sharing class ChildClass extends ParentClass" will use the sharing context of the calling class, not ParentClass Commented Dec 14, 2021 at 20:44
  • 1
    @DanWuensch Indeed. This answer was written before inherited sharing existed, so isn't present here. I resisted editing it in, because it's not in line with the question. That said, if we can figure out a way to make it make sense, I'd be happy to add it in. I think it might be worth being a new question, though.
    – sfdcfox
    Commented Dec 14, 2021 at 21:32
  • @sfdcfox was in an office debate yesterday about how the different scenarios work now that inherited was in play... we looked through popular questions but all are a few years old now. if anything it would make a great blog/article Commented Dec 15, 2021 at 22:04
  • 1
    @ŁukaszFranczyk Within the context of this answer, yes. However, we now have DML statements and more that can operate in either context without multiple classes being involved.
    – sfdcfox
    Commented Jul 17, 2023 at 15:31
7

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_keywords_sharing.htm

I am sure you would have read above link and lets clarify and touch upon each doubts

1)The object field level security and permissions are not followed even after you define class with "with sharing" keyword.If you are exposing this class for users who dont have proper access at profile level.The below article will tell us how we enforce this using apex and visualforce.

Note if you are using standard controllers and input field in your visualforce the field level security will apply and in case of output text or input text you will need to verify yourself with technique mentioned in below blog

http://wiki.developerforce.com/page/Enforcing_CRUD_and_FLS

2)The general rule of thumb is if its extended or implemented class then parent class context apply while if its inner class then the "withsharing" or "without sharing" keyword decides the behavior.If say none is specified then the caller class for the inner class (The class from which the inner class is called may not be container class)decides the behavior .

Lets solve your use cases

i)*class B extends A* // class B's code now executes in class A's mode, i.e. in "with sharing" mode.

You are correct since its extension class A mode apply

ii)*class B calls class A* // called code will now be executed in the mode of the class in which it was defined, in this case, in class A's mode, i.e. in "with sharing" mode.

Here Class A will be exceuted in with sharing mode and class B in without sharing mode as for each of the classes you have explicitly defined as with sharing or without sharing

iii)*class C calls class A* // called method's code in class A will execute in class A's mode, i.e. in "with sharing" mode.

The context of class C is defined from which the class is called .You have not specified how class C is called so assuming its independent without sharing keyword apply .Class A you have defined as with sharing so irrespective of from where this is called sharing rules will apply

iV)*class C extends class A* // code in class C now executes in the parent class A's mode, i.e. in "with sharing" mode.

yes you are right here .Since its extended class parent dominates the behaviour

v)*class A calls C* // code in class C is executed in class C's mode, i.e. in "without sharing" mode although it's sharing settings are unspecified in the class' declaration.

Class C has no keyword so the caller class i.e class A decides the behaviour and hence sharing rules apply

Vi)*class A extends C* // class A's code now executes in the parent class C's mode, i.e. in "without sharing" mode

If there is class calling class C then the sharing keyword of that paticular class controls behaviour of the class A .If not then you are right .

http://wiki.developerforce.com/page/Enforcing_CRUD_and_FLS

This article explains security for the visualforce controllers .Inputfield once used it considers the permissions and fls while output text and input text you will have to implement manually.Standard controllers the object permissions are considered when used with inputfield .

3
  • 4
    Not specifying a sharing model is not the same as specifying "without sharing." This is in regards to how you answered "iii". If they are calling the code from executeAnonymous, then C is "with sharing" for that call.
    – sfdcfox
    Commented Sep 2, 2013 at 4:24
  • Good to know !Never knew executeAnonymous obeys with sharing.I thought executeAnonymous works in system context . Commented Sep 2, 2013 at 8:15
  • What mode is it when Class A's method calls a method in Class B ?
    – Vignesh V
    Commented Sep 8, 2020 at 17:34
3

I think here is the Thumb Rule -

  1. if Key Word is used then

    • if it is a case of Extension , Parent class sharing setting will win.
    • if a class method calls method of other class , then sharing setting of called class will be in effect.
    • Inner class will have its own setting and does not inherit any thing from the container class. so it is behavior will be considered as i or ii.
  2. if the Key word is not declared for a class - Then always , sharing setting of the class which has declared will win always. Basically the class which is not declared with anything , will be driven by the sharing setting of the other class .

0

Without Sharing keyword -

The 'without sharing' keyword is to ensure that the sharing rules (not permissions) for the current user are not enforced.

Example - Let's consider that the OWD for Account is private, no account records are owned by or shared with an user 'u' and a "without sharing" class called MyClass is fetching account records in a list. Now if class 'MyClass' is run by user 'u' then account records will be fetched. Remember that whether the user 'u' is having full CRUD or having no CRUD, records will be fetched.

With Sharing keyword -

The with sharing keyword allows you to specify that the sharing rules (and not permissions) for the current user be taken into account for a class. You have to explicitly set this keyword for the class because Apex code runs in system mode.

Example - Let's consider that the OWD for Account is private, no account records are owned by or shared with an user 'u' and a "with sharing" class called MyClass is fetching account records in a list. Now if class 'MyClass' is run by user 'u' then no records will be fetched. Remember that whether the user 'u' is having full CRUD or having no CRUD record will not be fetched.

Some more things to note about sharing keywords:

The sharing setting of the class where the method is defined is applied, not of the class where the method is called. For example, if a method is defined in a class declared with with sharing keyword is called by a class declared with without sharing keyword, the method will execute with sharing rules enforced.

If a class isn’t 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.

Both inner classes and outer classes can be declared as with sharing.

The sharing setting applies to all code contained in the class, including initialization code, constructors, and methods.

Inner classes do not inherit the sharing setting from their container class.

Classes inherit this setting from a parent class when one class extends or implements another.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .