Public Anonymous Web Service on Salesforce Platform – No Login!


39645249So I was approached recently with the need to expose data to a vendor.  “Sure!” I thought…”What’s your endpoint, WSDL, and the format you want your data sent in?” was my initial response.

“No, we need to pull from you.” threw me for a loop – Salesforce ABSOLUTELY allows you to expose web services, but you need to establish a session first.  For an established vendor with 1,000’s of other clients they poll data from, there is no way in heck that they would change their process to add a log in component.

Hmmmph.  Well, let’s figure this out.  Salesforce is awesome, and there is always a way to do this.

Step 1:  Create your APEX Web Service

global class Generic_Whatever_Service {
webService static String yourWebService() {
String strReturnValue = 'Put whatever normal logic in here you would do';
return strReturnValue;
}
}

Step 2:  Create or Navigate to a Salesforce Sites instance

You’ll need to go in to the “Public Access Settings” button and configure the Guest Profile to be able to access your APEX class and any other objects that it may hit.

Step 3:  Download your WSDL and modify your endpoint

You’ll note that the endpoint in the WSDL is set to be https://yourinstance.salesforce.com/services/soap/class/name_of_your_class.  If you try to access this as it’s provided, you’ll be prompted for a sessionId, hence a login.

If you change your endpoint to be http://<your Sites URL>/<your Sites name if applicable>/services/soap/class/<name of your class> you’ll find that you now have a fully anonymous web service!

WAIT!  Don’t forget about security!

Honestly, there is no reason that you need to have a fully anonymously-accessible web service hosted by Salesforce.  The platform does a lot, but it’s just not geared for that IMHO.  (You should have an environment built for this if you are hosting data like that)

What I’ve done with the services I publish like this is to lock down access to it via the Guest Profile’s “IP Login Ranges”, found through the “Public Access Settings” button in Sites.  While this method doesn’t completely shut down access, people outside of your specified ranges will get an “INSUFFICIENT_ACCESS” error when trying to access your web service.

Questions?  Ask below.  =)

Advertisements

3 thoughts on “Public Anonymous Web Service on Salesforce Platform – No Login!

  1. Andy, Do you happen to have any javascript snippets that make the call to a REST endpoint on salesforce? I have been on this for quite a while and you are the most qualified for this sort of code. Hoping you can copy/paste a simple js client code snippet…
    Thanks:)

    • Hi Paul!

      Thanks for the question – I’ve had very limited success calling webservices via JS/jQuery rather than using server-side calls like PHP or .NET. One thing I noticed in there was your endpoint though – to call an APEX REST service, it’s “https://[instance]/services/apexrest/[your APEX REST “restresource” value]

  2. Forgot to post what I have tried.
    Seems like this sort of custom JS code would be a very common need in order to get around some of the salesforce rigid vf tags…

    Heres what I have been trying, with no luck:
    1. Manually created an account and got its id: 0015C000002XSx5
    2. Navigate to …/apex/TestAjax
    3. Click button, and it seems to do something, but does not Update the name

    run

    j$ = jQuery.noConflict();
    var weblink = “/services/apexrest/webprocessor”;//”apex/RecordListingUpload_View”;

    function callWS(){
    j$(“#wsOut”).val(“done”);

    j$.ajax(
    {
    url : weblink,
    type : ‘POST’,
    contentType: ‘application/json; charset=utf-8’,
    data: {
    “actionName”: “updateAccount”,
    “objAccount”: {
    “id”: “0015C000002XSx5”,
    “Name”: “Test Account 1”
    }
    },
    beforeSend: function (request)
    {
    request.setRequestHeader(“HeaderName”, “HeaderValue”);
    },

    crossDomain: false,
    success : function(result)
    {
    //process the result
    alert(“ajax-” + result);
    },
    error : function(jqXHR, textStatus, errorThrown) {
    alert(‘Error: ‘+jqXHR.status);
    alert(‘ErrorThrown: ‘+errorThrown);
    alert(‘a’+jqXHR);
    }
    });

    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s