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 Digest 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 unsuccessful 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);
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
soap_register_plugin(&soap, http_da); ... soap_serve(&soap); ... int ns__method(struct soap *soap, ...) { if (!soap->userid || !soap->passwd || strcmp(soap->userid, "<userid>") || strcmp(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().
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 }