Authenticating User Access

The following rule uses HTTP Basic authentication to ask the remote client for a user name and password. It checks the client’s user name, password, and IP address using a local Web server running an authentication application.

The rule looks for a header called “Authorization”. This should contain a string containing the word Basic, followed by a base-64 encoded string. When decoded, this string is of the form username:password.

If the string is malformed or the user name or password is absent, the rule returns a “401 Authorization Required” message to the client. This causes the user’s Web browser to prompt them for a user name and password.

If a user name and password have been supplied, the rule uses these details, together with the DNS name of the client, to query the local Web server using http.request.get(). The rule expects a “200 OK” response from the Web server to indicate success. Any response code other than 200 results in the rule sending the user the response “403 Forbidden”.

Note that if the user is successfully authenticated, the rule performs no positive action with the request. It is passed on to any other rules the Virtual Server is using, or its default pool.

# Determine the username and password, and send a

# '401 Authorization Required' header if there isn't

# one.

 

$authheader = http.getHeader( "Authorization" );

 

# Decode the Authorization header; it starts with

# 'Basic', followed by a base64 encoded

# username:password string

 

if( string.startsWith( $authheader, "Basic " ) ) {

$encuserpasswd = string.skip( $authheader, 6 );

$userpasswd = string.base64decode($encuserpasswd);

 

$i = string.find( $userpasswd, ":" );

$user = string.substring( $userpasswd, 0, $i-1 );

$password = string.skip( $userpasswd, $i+1 );

}

 

# If the client did not provide an Authorization

# header, indicate that authorization is required

if( $user == "" ) {

http.sendResponse( "401 Authorization required",

"text/html", "Please login\n",

"WWW-Authenticate: Basic realm=\"secure

server\"" );

}

 

# Check the supplied username and password by

# querying a local access server with the username,

# password and remote host.

 

$rhost = net.dns.resolveIP(connection.getRemoteIP());

 

$querystring = "user=" . string.escape( $user ) .

"&passwd=" . string.escape( $password ) .

"&rhost=" . string.escape( $rhost );

 

http.request.get(

"http://server/auth.cgi?" . $querystring );

 

if( $1 != 200 ) {

# access was denied

http.sendResponse( "403 Forbidden",

"text/html", "Access denied\n", "" );

}

 

# The user is allowed access

This rule could be optimized to cache responses from the local Web server, using data.set() and data.get().