Securing Your Web Service
Security is a very important aspect to consider when developing your services. As more and more business functions are exposed as web services, the boundary of interaction keeps expanding, and so does your responsibility to address all security requirements such as authentication, access control, data integrity, and privacy. In this section, we explore some ways to secure your web services.
To begin, you can always publish your web service over HTTPS. This approach will guarantee point-to-point security because SSL secures communications at the transport level. However, these scheme has limitations such as scalability issues, and you may not be able to use it.
You can also use your web server to control access to the directories containing your web services, or you can use ColdFusion security in the same way that you use it to control access to any ColdFusion page. The <cfinvoke> tag includes the username and password attributes that let you pass login information to a web server using HTTP basic authentication.
Using ColdFusion to Control Access
Let’s look at how to secure our web services from within ColdFusion. There are many possible ways to do so, and we will discuss just some of them here. You can pick the approach best suited to your particular needs.
One scheme that you can use uses <cflogin>. Rather than letting web servers handle authorization, you can implement authentication at the application level with Application.cfm (Listing 4.8).
Listing 4.8. /cfwack/4/secure/Application.cfm
<cfapplication name="wack4_secure"> <cflogin> <cfset authorized = false> <!--- verify username and password ---> <cfif isDefined("cflogin") and cflogin.name eq "foo" and cflogin.password eq "bar"> <cfset authorized = true> </cfif> </cflogin> <cfif not authorized> <cfsetting enablecfoutputonly="yes" showdebugoutput="no"> <cfheader statuscode="401"> <cfheader name="WWW-Authenticate" value="Basic realm=""Web Services"""> <cfabort> </cfif>
This Application.cfm example includes a <cflogin> tag. As you may know, the body of this tag runs only if there is no logged-in user. Therefore, the example includes some logic to validate the user in the body of the <cflogin> tag. In a real-world scenario, you would be validating users against a data source, LDAP, and so on. If the check here fails, the request is simply aborted, with a few authentication headers set. The same logic can be placed in the Application.cfc file’s method OnRequestStart. This method is executed for all types of requests and is invoked before the actual call to the web service method is made.
You can also use <cfloginuser> from within the <cflogin> tag to identify an authenticated user to ColdFusion and specify the user ID and roles. This approach lets you set allowed roles in <cffunction>, which can invoke that function.
Next, we explore how to invoke the same old hello web service, using the code snippet shown in Listing 4.9.
Listing 4.9. /cfwack/4/secureclient/basic.cfm
<cfset wsURL = "http://localhost:1234/cfwack/4/secure/hello.cfc?wsdl"> <cfinvoke webservice="#wsURL#" method="helloWorld" returnvariable="result" username="foo" password="bar"> <h1> <cfoutput>#result#</cfoutput> </h1>
As you can see, we are using the same <cfinvoke> tag that we have been using to additionally pass username and password information. This information will be populated in the cflogin struct, accessible within the <cflogin> tag as the name and password that we will use to validate our user.
Another approach is to use Open Standard for Authorization (OAuth) authentication. This authentication protocol allows applications to access a user’s data in a secure way. Several good libraries for both publishing and consuming OAuth integrations are available in ColdFusion for you to investigate.
Finally, you can use SOAP headers for authorization purposes: for example, you can set Web Service Security (WSS) headers and validate them either at the application level or the component level, as described in the next section.