gSOAP HTTP Digest Authentication:
Main Page | Class List | File List | Class Members | File Members | Related Pages
Additional build steps required:

Client-Side Usage

HTTP Basic Authentication is the default authentication supported by gSOAP. The credentials for client-side use age set with:

soap.userid = "<userid>";
soap.passed = "<passwd>";
if (soap_call_ns__method(&soap, ...))
  ... // error

HTTP Basic Authentication should never be used over plain HTTP, because the user ID and password are sent in the clear. It is safe(r) to use over HTTPS, because the HTTP headers and body are encrypted.

The better alternative is to use HTTP Digest Authentication, which uses the digest (hash value) of the credentials and avoids a plain-text password exchange.

To use HTTP Disgest Authentication with gSOAP, register the http_da plugin:

#include "httpda.h"
soap_register_plugin(&soap, http_da);

To make a client-side service call:

struct http_da_info info;
http_da_save(&soap, &info, "<authrealm>", "<userid>", "<passwd>");
if (soap_call_ns__method(&soap, ...))
  ... // error

The "<authrealm>" is a string that is associated with the server's realm. It can be obtained after an unsuccesful non-authenticated call:

if (soap_call_ns__method(&soap, ...))
{
  if (soap.error == 401) // HTTP authentication is required
  {
    const char *realm = soap.authrealm;
    ...
  }
  else
    ... // error
}

Before a second call is made to the same endpoint that requires authentication, you must restore the authentication state and then finally release it:

struct http_da_info info;

http_da_save(&soap, &info, "<authrealm>", "<userid>", "<passwd>");
if (soap_call_ns__method(&soap, ...))
  ... // error

http_da_restore(&soap, &info);
if (soap_call_ns__method(&soap, ...))
  ... // error

soap_destroy(&soap); // okay to dealloc data
soap_end(&soap);     // okay to dealloc data

http_da_restore(&soap, &info);
if (soap_call_ns__method(&soap, ...))
  ... // error

http_da_release(&soap, &info);
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);

Client Eample

soap_register_plugin(&soap, http_da);
// try calling without authenticating
if (soap_call_ns__method(&soap, ...))
{
  if (soap.error == 401) // HTTP authentication is required
  {
    if (!strcmp(soap.authrealm, authrealm)) // check authentication realm
    {
      struct http_da_info info; // to store userid and passwd
      http_da_save(&soap, &info, authrealm, userid, passwd);
      // call again, now with credentials
      if (soap_call_ns__method(&soap, ...) == SOAP_OK)
      {
        ... // process response data
        soap_end(&soap);
        ... // userid and passwd were deallocated (!)
        http_da_restore(&soap, &info); // get userid and passwd after soap_end()
        if (!soap_call_ns__method(&soap, ...) == SOAP_OK)
          ... // error
        http_da_release(&soap, &info); // free data and remove userid and passwd

Server-Side Usage

Server-side HTTP Basic Authentication can be enforced by simply checking the soap.userid and soap.passwd values in a service method that requires client authentication:

soap_register_plugin(&soap, http_da);
...
soap_serve(&soap);
...
int ns__method(struct soap *soap, ...)
{
  if (!soap->userid || !soap->passwd || strcmp(soap->userid, "<userid>") || strmp(soap->passwd, "<passwd>"))
    return 401; // HTTP authentication required
  ...
}

HTTP Digest Authentication is verified differently:

soap_register_plugin(&soap, http_da);
...
soap_serve(&soap);
...
int ns__method(struct soap *soap, ...)
{
  if (soap->authrealm && soap->userid)
  {
    passwd = ... // database lookup on userid and authrealm to find passwd
    if (!strcmp(soap->authrealm, authrealm) && !strcmp(soap->userid, userid))
    { 
      if (!http_da_verify_post(soap, passwd)) // HTTP POST DA verification
      {
        ... // process request and produce response
        return SOAP_OK;
      }
    }
  }
  soap->authrealm = authrealm; // realm to send to client
  return 401; // Not authorized, challenge with digest authentication

The http_da_verify_post() function checks the HTTP POST credentials. To verify an HTTP GET operation, use http_da_verify_get().

Server Example

soap_register_plugin(&soap, http_da);
...
soap_serve(&soap);
...
int ns__method(struct soap *soap, ...)
{
  if (soap->userid && soap->passwd) // Basic authentication
  {
    if (!strcmp(soap->userid, userid) && !strcmp(soap->passwd, passwd))
    {
      ... // can also check soap->authrealm 
      ... // process request and produce response
      return SOAP_OK;
    }
  }
  else if (soap->authrealm && soap->userid) // Digest authentication
  {
    passwd = ... // database lookup on userid and authrealm to find passwd
    if (!strcmp(soap->authrealm, authrealm) && !strcmp(soap->userid, userid))
    { 
      if (!http_da_verify_post(soap, passwd)) // HTTP POST DA verification
      {
        ... // process request and produce response
        return SOAP_OK;
      }
    }
  }
  soap->authrealm = authrealm; // realm to send to client
  return 401; // Not authorized, challenge with digest authentication
}

HTTP Digest Authentication Limitations

HTTP Digest Authentication cannot be used with streaming MTOM/MIME/DIME attachments. Streaming is turned off by the plugin and attachment data is buffered.
Generated on Thu Apr 22 14:04:00 2010 for gSOAP HTTP Digest Authentication by doxygen 1.3.8