![]() |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Basic Authentication
Basic Authentication Scheme is defined in section 11.1 of RFC 2068 (HTTP 1.1 Protocol). Here is its entire content:
### Extract from RFC 2068.
11.1 Basic Authentication Scheme
The "basic" authentication scheme is based on the model that the user
agent must authenticate itself with a user-ID and a password for each
realm. The realm value should be considered an opaque string which
can only be compared for equality with other realms on that server.
The server will service the request only if it can validate the
user-ID and password for the protection space of the Request-URI.
There are no optional authentication parameters.
Upon receipt of an unauthorized request for a URI within the
protection space, the server MAY respond with a challenge like the
following:
WWW-Authenticate: Basic realm="WallyWorld"
where "WallyWorld" is the string assigned by the server to identify
the protection space of the Request-URI.
To receive authorization, the client sends the userid and password,
separated by a single colon (":") character, within a base64 encoded
string in the credentials.
basic-credentials = "Basic" SP basic-cookie
basic-cookie = <base64 [7] encoding of user-pass,
except not limited to 76 char/line>
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT
Userids might be case sensitive.
If the user agent wishes to send the userid "Aladdin" and password
"open sesame", it would use the following header field:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
See section 15 for security considerations associated with Basic
authentication.
### End of extract.
Browser Behaviour for Virtual Directories with Basic AuthenticationWhat happens when a browser is pointed to a URL with basic authentication? First it tries to access the URL anonymously. Refer to network traffic captures (described in the end of this section) to observe actual data sent over the network between the browser and IIS. IIS returns error code 401 (Access Denied), informs the client that it supports basic authentication schema for the resource in the "WWW-Authenticate: Basic" header, then immediately disconnects the socket. The browser then asks user to enter user name and password (see Figure below).
Intenet Esplorer 5.00.3103.1000 asks user for authentication information.
The browser then opens another socket for communication with the web server, embeds authentication info in the Authorization header and sends another HTTP GET request. IIS logs a user onto the machine using his/her user name and password. The thread that handles the request obtains security context of a user, and tries to access a resource as if actually being this user. If NTFS permissions allow for access, then IIS replies with resource data. I have created a small code sample that uses basic authentication schema to get a web page from a web server. This sample is called HttpBasicClient. It is a little bit different from HttpAnonymousClient already described above. The difference is that I insert the Authorization header into the GET request. Take a look at its main function.
#include <winsock.h>
#include "comm.h"
#include "http.h"
#define BUFSIZE (64*1024)
// Main.
int main(int argc, char *argv[])
{
SOCKET s;
unsigned long cbRead;
unsigned long cbSize = BUFSIZE;
char achData[BUFSIZE];
// Change as necessary.
char * pszServer = "localhost"; // Notice that this might be an IP address, such as
// 10.1.5.148 or a resolvable full name of the machine
// such as webserver.mycompany.com.
char * pszDoc = "/1/1.htm";
// Initialize Winsock.
if (!InitWinsock())
return -1;
// Connect to server.
if (!ConnectSocket(pszServer, &s))
return -1;
// Build an HTTP GET request with basic authentication info.
buildBasicGet(achData, &cbSize, pszDoc);
if (!SendBytes(s, (unsigned char *) achData, strlen(achData)))
return -1;
// Receive data from server.
if (!ReceiveBytes(s, (unsigned char *) achData, BUFSIZE, &cbRead))
return -1;
// Display received data.
::MessageBox(NULL, achData, "Data returned from web server", MB_OK | MB_ICONINFORMATION);
// Terminate socket.
CloseSocket(s);
TermWinsock();
return 0;
}
As can be seen from the above code sample, I call the buildBasicGet function to prepare an HTTP GET packet. Here is its implementation.
#include <string.h>
#include "base64.h"
static char Headers[] = "HTTP/1.0\r\n"
"User-Agent: HttpBasicClient\r\n"
"Content-type: text/html\r\n"
"Accept: */*\r\n"
"Connection: Keep-Alive\r\n";
/*
* buildBasicGet
* Builds an HTTP GET request with embedded basic authentication information.
*
* Parameters:
* pData - data buffer to build a request in.
* pcbSize - points to data size.
* pURL - URL.
* Returns - 0 if we are okay.
*/
int buildBasicGet(char * pData, unsigned long * pcbSize, char * pURL)
{
// Clear text user name and password. Change as necessary.
const char user[]="TestUser";
const char pwd[]="password";
memset(pData, 0, *pcbSize);
strcpy(pData, "GET ");
strcat(pData, pURL);
strcat(pData, " ");
strcat(pData, Headers);
// Prepare clear text authorization string.
char authstr[256] = {0};
strcat(authstr, user);
strcat(authstr, ":");
strcat(authstr, pwd);
// Base64 encode the authorization string.
char * b64_auth = base64_encode((unsigned char*) authstr, strlen(authstr));
// Append the authorization string.
strcat(pData, "Authorization: Basic ");
strcat(pData, b64_auth);
strcat(pData, "\r\n");
strcat(pData, "\r\n");
// Release memory.
if (b64_auth)
delete b64_auth;
return 0;
}
So, to summarize, if a client is using the basic authentication schema, it must supply the Authorization: header, containing base64 encoded user name and password separated by a semicolon. As already mentioned in RFC 2068, for user named "Aladdin" and password "open sesame", the header must look like Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== My sample code for hard-coded user name "TestUser" and password "password" builds this header as Authorization: Basic VGVzdFVzZXI6cGFzc3dvcmQ= The complete list of headers that my sample provides is presented below: GET /1/1.htm HTTP/1.0 User-Agent: HttpBasicClient Content-type: text/html Accept: */* Connection: Keep-Alive Autorization: Basic VGVzdFVzZXI6cGFzc3dvcmQ= This list is followed by 2 CRLFs. As in the previous section I have captured network traffic between client applications and IIS for reference. The complete list of related traffic captures is summarized in the following table.
|