Previous section   Next section

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 17.  Socket Programming

Basic Authentication

Web pages are often password protected. The most common form of this uses a protocol called Basic Authentication, which is not very strong, but easy to implement. With this scheme, the server responds to an HTTP request with a 401 error status and a Www-Authenticate header, which specifies the authentication protocol the server wants to use. For example, the server response can contain the following information:

HTTP/1.0 401 Authorization Required
Www-Authenticate: Basic realm="My Pages"

The realm is meant to be an authentication domain. In practice, it is used in the string that gets displayed to the user as part of the password prompt. For example, a Web browser will display this prompt:

Enter the password for My Pages at www.beedub.com

After getting the user name and password from the user, the Web browser tries its HTTP request again. This time it includes an Authorization header that contains the user name and password encoded with base64 encoding. There is no encryption at all ?anyone can decode the string, which is why this is not a strong form of protection. The Tcl Web Server includes a base64.tcl file that has Base64_Encode and Base64_Decode procedures. Example 17-13 illustrates the Basic Authentication protocol. http::geturl takes a -headers option that lets you pass additional headers in the request.

Example 17-13 Basic Authentication using http::geturl.
proc BasicAuthentication {url promptProc} {
   set token [http::geturl $url]
   http::wait $token
   if {[string match 401* [http::status $token]]} {
      upvar #0 $token data

      # Extract the realm from the Www-Authenticate line

      array set reply $data(meta)
      if {[regexp {realm=(.*)}$reply(Www-Authenticate) \
             x realm]} {

         # Call back to prompt for username, password

         set answer [$promptProc $realm]
         http::cleanup $token

         # Encode username:password and pass this in
         # the Authorization header

         set auth [Base64_Encode \
             [lindex $answer 0]:[lindex $answer 1]]
         set token [http::geturl $url -headers \
             [list Authorization $auth]]
         http::wait $token
   return $token

Example 17-13 takes a promptProc argument that is the name of a procedure to call to get the username and password. This procedure could display a Tk dialog box, or prompt for user input from the terminal. In practice, you probably already know the username and password. In this case, you can skip the initial challenge–response steps and simply supply the Authorization header on the first request:

http::geturl $url -headers \
    [list Authorization \
        "Basic [Base64_Encode $username:$password"]]

      Previous section   Next section