Explanation: Background to HTTP Authentication
Scenario: The server has some resources that are restricted and should only be served up to authorised users. These are kept in a specific area of the server known as a "realm" (physically, this may be the files on a particular directory and its sub-directories). Authorised users are identified (Authenticated) by a username and password. We are not worried here, how the username and password are created or stored - just that they exist and are known to the server.
The HTTP 1.1 protocol has built in mechanisms to support this.
The simplest is "Basic authentication". The way this works is:
- the client (your web-browser) requests a resource that is located in the protected realm
- the server sees that this resource requires basic authentication and sends back an error "HTTP Error 401 - Unauthorized". The HTTP header of this response tells the client that basic authentication is required - i.e. the server wants a username and password.
- the client prompts the user for their username and password (the ubiquitous login dialog box!) and then re-sends the request, this time including the username and password encoded in the HTTP header
- the server checks that the username and password are valid and serves up the requested resource.
This is pretty straightforward and easy to understand (and very widely used), but its drawback is that the username and password are sent over the internet in the HTTP header as plain text. So anyone who can access the stream of messages going backwards and forwards (e.g. someone using a packet sniffer at some intermediate internet node) can easily get your username and password.
The system used by the NBN Gateway is "Digest authentication". It is a bit more secure, but more complicated. It provides a way of telling the server that the client knows the user's password without having to actually send it. The trick is that the server sends the client a token called a "nonce" ("n once" - a number that is valid for one time only) and the username, password and nonce (and some other parameters) are combined using a one-way hashing algorithm (md5). It is the result of this md5 hash that are sent to the server. The server can do exactly the same calculation at its end and, if the answers agree, then both client and server must be using the same username/password combination and the server can authenticate the user.
So the process is:
- the client (your web-browser) requests a resource that is located in the protected realm
- the server sees that this resource requires digest authentication and sends back an error "HTTP Error 401 - Unauthorized". The HTTP header of this response tells the client that digest authentication is required and includes the necessary parameters (nonce, etc).
- the client prompts the user for their username and password and combines them with the nonce and other parameters recovered from the HTTP header to calculate the md5 hash.
- the client re-sends the request, this time including the username and md5 hash in the HTTP header
- the server reads the username, accesses its own copy of that user's password and calculates the md5 hash using the nonce and other parameters it previously sent. If the results are the same as those passed back by the client, the user is authorised and it can serve up the requested resource.
The advantage of this is that the password is not sent. Somebody who can access the message stream can see the username and hash, but the nature of the hashing process makes it impossible to recover the password from it. The nonce is also designed to have a limited lifetime so that the particular hash is only valid for a limited time (typically some number of seconds). This protects you password, but is still not particularly secure because the protected resource is returned as plain text. So the snooper in the middle still gets to see it, even if they cannot get your password!
The NuSoap library includes a method to allow for various types of authentication: setCredentials(username, password, authentication_type, parameters)
- username and password are strings. Note that these are case sensitive! This is not normally the case when you login to the NBN Gateway, but IT IS the case in this context. They must match EXACTLY the Gateway's version.
- authentication_type is a string which can be "basic" or "digest" (or other options we don't need to worry about)
- if authentication_type is "digest", then parameters is an associative array with the fields realm, nonce, qop and opaque which are recovered from the 401 error message's HTTP header returned by the server.
So, what we need to do to achieve a NuSoap connection to secured NBN web-services is:
- request some resource on the NBN Gateway server's secured realm
- get back a 401 error and recover the necessary parameters from it
- instantiate our NuSoap client, passing it the URL of the NBN Gateway's secure WSDL
- call its setCredentials method with a valid username and password and with the parameters recovered from the 401 error header
We can then use the client object to make web-service requests as usual. Because we asked for the secured version of the WSDL, these will be the secured versions of the web-service calls. NuSoap will handle the digest authentication dialog with the server.
Just for the sake of completeness, if we want to be really secure we would need to use the HTTPS/SSL (Secure Socket Layers) system in which all the messages passed backwards and forwards are encrypted. NuSoap can supports this - the third, authentication_type, parameter is "certificate". This is not supported by the NBN Gateway and is outside the scope of what we are doing here, but the downside is that everything has to be encrypted before it is sent and decrypted when it is received, so there is a considerable overhead on both server and client. So it should only be used when REALLY necessary (like sending your credit card details!).