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_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>") || 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
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 }