How to Create an .A5W Page that Requires Basic Authentication

Description

Basic Authentication is a simple HTTP form of authentication which can be used to restrict access to your server or web service.

Discussion

Basic Authentication is a simple HTTP form of authentication. As defined in Wikipedia:

"HTTP Basic authentication (BA) implementation is the simplest technique for enforcing access controls to web resources because it doesn't require cookies, session identifier and login pages. Rather, HTTP Basic authentication uses static, standard HTTP headers which means that no handshakes have to be done in anticipation."

If you create simple web services in Alpha Anywhere, you might want to use basic authentication on the .a5w page that implements your web service.

The example below demonstrates a robust way to implement this. It defines two helper functions: Authenticated() to validate credentials, and AuthenticationPrompt() to handle the standard HTTP 401 challenge if validation fails.

In this trivial example, the only valid User ID/Password combination is Alpha/Anywhere. However, you can easily modify the Authenticated() function to perform a database lookup.

<%a5
' Main Page Logic
if .not. Authenticated() then
    ' If user is not valid, send 401 Challenge and Stop
    AuthenticationPrompt()
    Response.End()
else
    ' User is valid. Page content follows below.
    %>
    <html>
    <head><title>Protected by Basic Authentication</title></head>
    <body>
    <h2>You are Authenticated</h2>
    <p>You cannot see this page unless you have passed HTTP Basic Authentication.</p>
    <p>The current time on the server is <%a5 ? time() %> </p>
    </body>
    </html>
    <%a5
end if

' Function to check credentials
function Authenticated as l ()
    Authenticated = .f.
    if ("Authorization: Basic " $ Request.Headers)
        dim EncodedUserAndPass as c = extract_string(Request.Headers, "Authorization: Basic ", crlf())
        dim DecodedUserAndPass as b = base64decode(EncodedUserAndPass)
        dim Username as c = word(DecodedUserAndPass, 1, ":")
        dim Password as c = word(DecodedUserAndPass, 2, ":")
        
        ' REPLACE THIS with your own database/security lookup
        if (Username = "Alpha" .and. Password = "Anywhere")
            Authenticated = .t.
        end if
    end if
end function

' Function to send 401 Challenge
function AuthenticationPrompt as v ()
    Response.StatusCode = "401"
    Response.StatusDescription = "Not Authorized"
    Response.Headers.Add("WWW-Authenticate", "Basic")
end function
%>

See Also