I am in the process of creating a simple Web Service for a Client of our's who wants the ability to retrieve shopping cart information and add/update items in the cart. I have written a CFC with a remote method for each. Now, obviously when these CFC methods are set to access="remote"
, the entire world can call them as is. However, I need to enable security to ensure that the only people that can call these methods remotely (not from within my website) are those that I've given permission to. And I don't want it to be intrusive (forcing a login, etc.).
For example, the Web Services exist on http://www.mywebsite.com and I only want to permit requests from http://www.yoursite1.com and http://www.yoursite2.com. Using HTTP_REFER
is no good, since this can be spoofed. How can I do this? Is it possible to use a self-signed certificate to somehow verify that the request is allowed?
NOTE: I'd also like to be able to use these Web Services for calls from our own website, so I'll need a solution that works for both scenarios.
I'm actually faced with the same issue. I was thinking about issuing a secret key to the consumer of my web service and getting their IP address. Then, on a web service call, they would need to send the secret key in the header section. I would then validate the request based on secret key and remote address. I'm sure there are better ways of doing this, and I'll be intrested in what others will be offering.
I think your best bet will be to setup a proxy web service on the client sites. You'll very likely need this in any case, since otherwise the users of those sites will be hit with the cross-domain access restrictions (ajax requests are typically only allowed back to the domain of the originally-requested page).
So for example, you have a webservice here: https://www.mywebsite.com/myService.cfc?wsdl
On each of the client sites there will be another webservice, something like this:
http://www.yoursite1.com/myServiceProxy.cfc?wsdl
myServiceProxy.cfc will look something like this:
<cfcomponent>
<cffunction name="getData" access="remote" returnType="struct">
<cfargument name="myArg1"><!--- whatever is needed for your service --->
<cfset var ret = {}>
<cfset var secretKey = "MySuperSecretSharedKey">
<cfif IsDefined("session.validUser")><!--- whatever is needed to validate remote user --->
<cfinvoke
webservice="https://www.mywebsite.com/myService.cfc?wsdl"
method="getData"
returnVariable="ret">
<cfinvokeargument name="secretKey" value="#secretKey#">
<cfinvokeargument name="myArg1" value="#arguments.myArg1#"><!--- etc.... --->
</cfinvoke>
</cfif>
<cfreturn ret>
</cffunction>
</cfcomponent>
As you can see from this example, the proxy code will be able to check if the user is valid, based on the session or whatever else is necessary. Then, because this proxy code has been configured with a secret key, that can be passed back to your real service. Using that secret key, you can verify that the caller of your service is valid (also make note of the HTTPS - definitely a good idea here). That should be it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With