[SalesForce] Sharing / without sharing and @RemoteAction

I have a global class (without sharing). One of its method is a @RemoteAction, which instantiate another class (public and without sharing) and uses one method of the instantiated class. This method tries to modify some field on an object.

Since "with sharing" is not written in the declaration of both classes I'd expect that the code is executed without considering the current user. Nonetheless an error is thrown because the current user doesn't have the permissions to do the modification.

Can you please help me understand what is going on :)?

Thank you very much,
T.

EDIT: I've created a simple class to test the following strange behavior, the remote action of the "global class" throws permission error, while the normal action.. doesn't! The behavior of the normal action apparently is different from the remote one with respect to the "default/with sharing/without sharing".

If, as suggested, the token "without sharing" is added to the global class then both normal and remote method works.

    //
    // create an opportunity o with a user, then run this class with a user which has no
    // permissions to write on o
    // the behavior of remote action and normal action is different if there is no 
    // "without sharing" token
    //

`global class controllerTestSharing{`

    public opportunity o {get;set;}
    public controllerTestSharing(){
        o = [select name,description from opportunity where id =: ApexPAges.currentPage().getParameters().get('oppId')];    
    }

    global void normaleUpdate(){
        update o;
    }

    @remoteAction
    global static string remoteUpdate(string oppId,string descr){
        opportunity o = new opportunity(id=oppId,description=descr);
        try{
            update o;
        }catch(exception e){ return e.getMessage(); }
        return 'ok';
    }

}

Best Answer

The standard behaviour is "with sharing", and if you don't want this you need to declare the class "without sharing". 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.

In API releases up to 29, if a @RemoteAction method was called on a class that didn’t explicitly declare with sharing or without sharing, the method ran as though the class was declared with sharing. In other words, the default behavior was different for methods depending on whether they were invoked as part of a standard Visualforce request or a JavaScript remoting request. This wasn’t intended behavior.

Beginning with API 30.0, requests execute consistently, regardless of how the class is declared, or how the method is invoked:

  • By default, without a sharing declaration, the method operates in
    system mode, as though the class was declared without sharing.

  • Methods in classes declared without sharing operate in system mode.

  • Methods in classes declared with sharing respect the user’s organization-wide defaults, role hierarchy, and sharing rules.

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