Introduction.
To use X509 authentication in a web page you need HTTPS. To have a HTTPS server working for a domain, you
need a different IP for every server (or group of servers, if you use expensive wildcard certificates).
If you do not have money to get a SSL certificate for every server, or you have not enough IPs,
you can use this simple protocol.
The implementation is done with PHP.
Implementation
HTTP script that wants client authentication:
// step 1
if (! $_SESSION['authenticated']) {
$sslServer='https://serverwithTLS/authScript.php';
$myscr='http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
$reto_auth=$_GET['reto_auth'];
// step 5: 'reto_auth' is given by step 4
if ($reto_auth) {
// step 6: connects to obtain auth data
$data=unserialize(file_get_contents("$reto_auth"));
"test $data against valid users"
if ($ok)
$_SESSION['authenticated']=$data;
else
die("Unknown user");
// hide authetication details and recover URL
header("Location: $myscr?".$_SESSION['QS']);
die();
}
else {
if ($_GET['wantauth'])
// step 2
header("Location: $sslServer?reto=yes&url=".urlencode("$myscr?extraparams&"));
else {
$_SESSION['QS']=$_SERVER['QUERY_STRING'];
die("Please, click <a href=\"$myscr?wantauth=yes\">here</a> to authenticate");
}
die();
}
}
HTTPS authentication script must be configured with TLS authentication optional, or it should be really two scripts, one
with TLS authentication required, the other without authentication.
// step 6
// no authentication required, based on session
if ($_REQUEST['rauth']) {
// returns serialized session from step 3
echo serialize($_SESSION);
session_destroy();
session_unset();
}
else {
// step 3
// no database required, using $_SESSION
"take certificate data"
// authetication with valid certificated has been suggested by server
if ($correct) { // certificate present, some certificate field required, etc.
$_SESSION[.......]="certificate data"
if ($_GET['reto']) {
// builds step 4
$rah='reto_auth='.urlencode('
https://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].
'?rauth=yes&PHPSESSID='.session_id());
// step 4
// url should end whit & or ?
header("Location: ".$_GET['url'].$rah);
}
else
die("Bad invocation");
}
else
// message will be shown only if authentication is optional
die("No certificate or not valid for this purpouse");
}
Security is based in the random nature of PHPSESSID.