Monday, 3 October 2011

Secured Web Services in ColdFusion

One day I just felt the need to create a Secured ColdFusion Web Service and to my wonder I just found good examples of consuming it but none for publishing it. That influenced me to write a  blog for Web Service published in ColdFusion, consumed in ColdFusion and that too in a secured manner using <cfinvoke>/<cfobject>  username/password feature.

Without giving the overview I will just get into the details but before that it's must to understand that how is ColdFusion behaving from client side . From client side when you give username/password in <cfinvoke> tag or <cfobject> tag (see the sample code below), then ColdFusion sends the information as part of the request. The login information is passed to web server using HTTP basic authentication.

Please note that these are just code snippets. I will share the complete code in the end.

You just saw how easy it is to consume a web service in ColdFusion. Publishing also is a very simple task but there is a twist. ColdFusion doesn't give any specific feature to handle the authentication (username/password) sent by client-side(using cfinvoke/cfobject). But that doesn't mean you can not handle it. ColdFusion has already given an awesome feature of <cflogin> and expects the user to authenticate the credentials using that same feature.

Here is snippet of <cflogin> authentication.

Please read the comments inline to understand the code.

We just saw how to catch the username and password sent in request by cfinvoke but the question is where to use it. I will suggest to use this code in Application.cfc instead of web service component. The reason is, it could save you a lot of code rewriting and easy to maintain. You can just write the code once in Application.cfc in onRequestStart() method and for every request it will ask for authorization otherwise will  send UnAuthorized status.

I hope you got an idea of how to consume a web-service with credentials and how to publish a web-service which gives on access on proper authorization.

So now I will post the complete code for doing this. There will be three files namely: securedws.cfm, securedws.cfc and Application.cfc. I am assuming that ColdFusion9(installed in C:\) is used and these files are kept under C:/coldfusion9/wwwroot/securedwebservices/
Please change the URL of webservices in code given below accordingly if your configuration is different.

Please note that for consuming the web-services always prefer <cfinvoke> tag over <cfobject>. cfobject tag has one limitation, it caches the first username/password and then even if you will change the credentials, it will send the first credentials only.

For example, consider that there are two users for your webservice with two credentials lets say: user1/pass1 and user2/pass2.

First lets use cfobject with credentials of first user(user1/pass1) and try to access the web-service. It will send the correct credentials to web-service. Now change the credentials in the same cfobject and use second user's one(user2/pass2) and access the webservice. This time request should have send second user's credentials(user2/pass2) but it actually passes (user1/pass1). You can confirm this behavior using <cfdump output="console" var="#cflogin#"> at server side.

This behavior is only observed with cfobject only and is quite dangerous. So I will suggest you to use cfinvoke.

Feel free to post any queries.

ColdFusion Rocks!!!