Background
In the basic authentication scheme, username and password are transferred base64 encoded in the Authorization header of the HTTP request. So in the WebHandler this header must be accessed and the username and password must be extracted from the header value and checked.The Authorization header follows the following convention:
Code:
Header: "Authorization"
Value : "Basic <credentials>" // "<credentials>" is a Base64-encoded
// string with the client's credentials
// specified as "<user>:<password>".
Example
The task of authorization is implemented in the BasicAuthorization() class in the code example below. The usage is illustrated here using the CurrentTime:get() method from the documentation of the WebHandler class:
Xbase++:
METHOD CurrentTime:get()
...
IF .NOT. BasicAuthorization():verify( ::HttpRequest, ::HttpResponse )
RETURN "Access denied"
ENDIF
...
RETURN cResponse
Code:
// positive test
curl http://localhost:81/CurrentTime/get -u "login:password"
// invalid password curl
curl http://localhost:81/CurrentTime/get -u "login:invalid"
// no credentials
curl http://localhost:81/CurrentTime/get
Xbase++:
//////////////////////////////////////////////////////////////////////
///
/// <summary>
/// The class BasicAuthorization verifies credentials according to
/// an HttpRequest object. On error the HttpResponse object gets the
/// status code 401 set.
/// </summary>
///
///
/// <remarks>
/// The class method :verifyCredentials() needs to be extended according
/// to your infrastructure.
/// </remarks>
///
///
/// <copyright>
/// Alaska Software. All Rights Reserved.
/// </copyright>
///
//////////////////////////////////////////////////////////////////////
/// <summary>
/// </summary>
CLASS BasicAuthorization
PROTECTED:
CLASS METHOD extractCredentials
CLASS METHOD verifyCredentials
EXPORTED:
CLASS METHOD verify
ENDCLASS
/// <summary>
/// Verify basic authorization according the httprequest Authorization header.
/// Set status code and message on failure.
/// </summary>
CLASS METHOD BasicAuthorization:verify( oHttpRequest, oHttpResponse )
LOCAL cAuthorizationHeader
LOCAL cUser, cPass
cAuthorizationHeader := oHttpRequest:getHeader( "Authorization" )
cUser := cPass := NIL
IF .NOT. ::extractCredentials( cAuthorizationHeader, @cUser, @cPass )
oHttpResponse:setStatus( 401, "Unauthorized" )
RETURN .F.
ENDIF
IF .NOT. ::verifyCredentials( cUser, cPass )
oHttpResponse:setStatus( 401, "Unauthorized" )
RETURN .F.
ENDIF
RETURN .T.
/// <summary>
/// Extract username and password from Authorization header.
/// </summary>
/// <param name="cAuthorization">The HTTP Authorization header value.</param>
/// <param name="cResultUser">Return the username in this reference parameter.</param>
/// <param name="cResultPass">Return the password in this reference parameter.</param>
/// <returns>
/// Return the logical value true (.T.) when authorization
/// succeeded. Return false(.F.) otherwise.
/// </returns>
CLASS METHOD BasicAuthorization:extractCredentials( cAuthorization, cResultUser, cResultPass )
LOCAL cUserPass
LOCAL nColPos
// Initialize the return values passed by reference
cResultUser := ""
cResultPass := ""
// Credentials are prefixed by "Basic "
IF .NOT. "basic " == Lower( SubStr( cAuthorization, 1, 6 ) )
RETURN .F.
ENDIF
// Username and password are base64 encoded
cUserPass := Base642Bin( SubStr( cAuthorization, 7 ) )
// and seperated by a colon
nColPos := At( ":", cUserPass )
IF 0 == nColPos
RETURN .F.
ENDIF
cResultUser := SubStr( cUserPass, 1, nColPos - 1 )
cResultPass := SubStr( cUserPass, nColPos + 1 )
RETURN .T.
/// <summary>
/// Verify credentials
/// </summary>
/// <returns>
/// Returns the logical value true (.T.) when credentials are valid and
/// false (.F.) otherwise.
/// </returns>
/// <remarks>Modify this method according your infrastructure</remarks>
CLASS METHOD BasicAuthorization:verifyCredentials( cUser, cPass )
IF .NOT. "login" == cUser
RETURN .F.
ENDIF
IF .NOT. "password" == cPass
RETURN .F.
ENDIF
RETURN .T.
Xbase++ documentation: Class WebHandler
Xbase++ documentation: Class HttpEndpoint
Homepage Homepage curl.exe
RFC 7617: The 'Basic' HTTP Authentication Scheme
Last edited: