Cross Origin (CORS) Enabled WCF Services Over SSL From Dynamics CRM
The latest W3C standard CORS specification addresses the issue that most browsers simply won’t allow cross domain calls for security reasons. Previous workarounds for Dynamics CRM calls to external web services have included transferring logic from client to server via a dialog or workflow with custom activity, the use of JSONP or using IIS URL rewrites.
The CORS specification details a solution which allows for checking of origin request headers to identify whether the source is indeed allowed to interaction with the server hosting the service and as such returns the appropriate headers. More details can be found here .
This blog displays the steps required to call an external web service hosted on WCF via Rest over SSL.
First, a few assumptions and checks:
• SSL self cert or purchased has been installed on the server.
• CRM version is 2011 on premise and is running IFD with claims based authentication
• You have access to IIS on the server to check/tweak SSL settings – due to IE being IE
• Ensure the service being called (if you are not developing it yourself) is enabled for CORS.
• Ensure that the browsers you need to support as part of your development are listed here.
• I will assume that you have already created and deployed a rest enabled web service to IIS.
Server Side Development
The CORS website advises that server side configuration required involves adding an httpProtocol entry into the web.config file of the deployed service as per here. I instead decided to implement this functionality as part of the Application_BeginRequest event within my global class. This then allowed for greater control over the sites allowed access to my web service.
The pre-flight request, which checks for authorisation changes the HTTP verb to OPTIONS and as such the check is placed within this condition. Additional headers are self-explanatory but the Access-Control-Allow-Origin is key in telling the browser that if the request came from the calling origin it may continue to progress with the request.
I created a quick test contract to be called via a GET request from our CRM form as per below. This would return an object OptionSetReturn which contains a key value pair dictionary called OSDictionary.
At this point, we have satisfied all of the requirements for CORS server side development and our test setup. However, we’ll be back for a gotcha later!
With everything in place we can test out web service call. Fire the call by changing the option set value on the form and fire up FireBug or your choice of front end debugger and watch the values being returned.
So we have out CRM call working in FF and Chrome but IE still gives us the dreaded “Access Denied” error with no additional error information to help us out. The reason this happens is that IE, by default, will automatically deny all cross origin requests.
In order for IE to not block our request we would typically have to set the “Access data sources across domains” for our internet zone as per below.
Typically we won’t be able to roll out this change for all users of the application but if we have access to our server hosting out web service we can change the SSL settings without having to touch user browsers.
SSL settings >> Required = true and then Ignore selected
Prevents you from having to change the “Access data sources across domains” flag within IE right.