Authentication protocol with certificates on HTTP servers.

April 2006

  1. Objective
  2. Introduction.
  3. Steps.
  4. Implementation
  5. Nisu topics.

Objective

This document describes a simple way to cperform authentication with X509 on a HTTP erver (no TLS) using an auxiliar HTTPS server in a different domain, without cookies.

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 everuy server (or gourp of server if you use expensive wildcard certificates). If you do not have money to get a SSL certificate or you have not enough IPs, you can use this simple protocol.
The implementation is done with PHP.

Steps.

  1. Client connects whit HTTP server.
  2. If not authenticated, server redirects (using Location header) to the HTTPS authentication URL, indicating the return URL.
  3. The HTTPS URL performs X509 client authentication, opening a session for the client, and if authentication is successfull, stores data from certificate in session variables.
  4. Then, redirects client to original HTTP server with an additional parameter indicating that auth is succesfull (URL1), containing another URL (URL2) to obtaining authentication data.
  5. Client goes HTTP server, URL1.
  6. HTTP server connect by itself to URL2, obtaining authentication data.

Implementation

HTTP script that requires authentication:
	$sslServer='https://serverwithTLS/authScript.php';
	// step 1
	if (! $_SESSION['authenticated']) {
	  $reto_auth=$_GET['reto_auth'];
	  // step 5: 'reto_auth' is given by URL1 in step 4
	  if ($reto_auth) {
	    // step 6: connects to obtain auth data
	    $data=unserialize(file_get_contents("$sslServer?$reto_auth"));
	    "test $data agains valid users"
	    if ($ok)
	      $_SESSION['authenticated']=$data;
	    else
	      die("Unknown user");
	    // hide authetication details and recover URL
	    header('Location: '.$_SERVER['SCRIPT_NAME'].'?'.$_SESSION['QS']);
	    die();
	  }
	  else {
	    // step 2
	    $_SESSION['QS']=$_SERVER['QUERY_STRING'];
	    header("Location: $sslServer?url=".
		urlencode('http://'.$_SERVER['HTTP_HOST'].
		$_SERVER['SCRIPT_NAME'].'?someOtherParameters').'&reto=si');
	    die();
	  }
	}
	
HTTPS Authentication script:
	$reto_auth=$_REQUEST['reto_auth'];
	// step 6
	if ($reto_auth == $_SESSION['reto_auth']) {
	  // returns serialized session from step 3
	  echo serialize($_SESSION);
	  session_destroy();
	  session_unset();
	}
	else {
	  // step 3
	  // no database required, using $_SESSION
	  // authetication with valid certificated has been required by server
	  if ($correct) { // optional: some certificate field required ?
	    $_SESSION[.......]="certificate data"
	    if ($_GET['reto']) {
	      $rh=uniqid('',true);
	      $_SESSION['reto_auth']=$rh;
	      // builds step 4
	      $rah='reto_auth='.urlencode('?reto_auth='.$rh.'&PHPSESSID='.session_id());
	      // step 4
	      header("Location: ".$_GET['url'].$rah);
	    }
	    else
	      die("Bad invocation");
	  }
	  else
	      die("Certificate not valid for this purpouse");
	}
	
Select Style - Legal