NuSphere Forums Forum Index
NuSphere Forums
Reply to topic
Client-server digest authentication example

Joined: 07 Mar 2014
Posts: 1
Location: Brasil
Reply with quote
I'm trying for a long time to implement a webservice with digest authentication using nusoap.
I allways get the same error: HTTP Error: Too many tries to get an OK response (HTTP/1.0 401 Unauthorized)

I just want some simple example that works with digest authentication.
Can anyone help me?

I'm trying the following:

Script client.php

require_once ('lib/nusoap.php');
require_once ('authenticate.php');

$service = 'http://localhost/testes/ws/server.php';
$wsdl   = $service.'?wsdl';
$secure = $service.'?secure';

$digest = getDigestToServer($secure); //implemented at authenticate.php script, below

$client = new soapclient($wsdl, true);
                                "realm"  => $digest["realm"],
                                "nonce"  => $digest["nonce"],
                                "nc"     => 0,
                                "qop"    => $digest["qop"],
                                "opaque" => $digest["opaque"],

  echo "<br>";
  echo "Getting professional code for '123.456.789-10','TÉCNICO'.<br>";
  $result = $client->call('getRegistro', array('123.456.789-10','TÉCNICO'));

  if($result == false){
    echo "Fail: <pre>".$client->getError()."</pre>";
    $erro = $client->getError();
      echo "Error: <pre>$erro</pre>";
      echo "SUCESS!<br>";
      echo "Answer (json): $result<br>";
  echo "<textarea id='txt1' name='txt1'>

Script server.php

  requireAuthentication(); //implemented at authenticate.php script, below

//Enable webservice
require_once ('lib/nusoap.php');

//using soap_server to create server object
$server = new soap_server;

//Configurando o serviço de consulta de registros
$server->configureWSDL('server.getRegistro', 'urn:server.getRegistro');
$server->wsdl->schemaTargetNamespace = 'urn:server.getRegistro';

//register a function that works on server
$server->register(  'getRegistro',                               //Nome da função
                    array(  'cpf'     => 'xsd:string',      //Parametros da função
                            'categoria' => 'xsd:string'),
                    array('return' => 'xsd:string'),          //Valor de retorno
                    'urn:server.getRegistro',                    //Namespace
                    'urn:server.getRegistro#getRegistro',           //SOAP Action
                    'rpc',                                    //Style
                    'encoded',                                //Use
                    'Consulta o número de registro de um profissional de enfermagem.' //Descricao do serviço

// create HTTP listener


function getRegistro($cpf, $categoria){
  include("authenticate.php"); //implemented below

  //This example works fine if you comment the line below. I'm not sure where to place this line
  requireAuthentication(); //implemented at authenticate.php script, below

  $rc = array();

  $rc["cpf"]       = preg_replace("([^0-9])", "", $cpf); //removing '.' and '-'
  $rc["categoria"] = utf8_encode($categoria);
  $rc["registro"] = date("dmYhis"); //returning professional code

  return json_encode($rc);

Script authenticate.php

$realm = 'my_realm_code';
$validUser = 'admin';
$validPass = '1234';

function requireAuthentication() //Used by server.php script, above
  global $realm, $validUser, $validPass;

  // Just a random id
  $nonce = uniqid();

  // Get the digest from the http header
  $digest = getDigest();

  // If there was no digest, show login
  if (is_null($digest)) requireLogin($realm,$nonce);

  $digestParts = digestParse($digest);

  // Based on all the info we gathered we can figure out what the response should be
  $A1 = md5("{$validUser}:{$realm}:{$validPass}");
  $A2 = md5("{$_SERVER['REQUEST_METHOD']}:{$digestParts['uri']}");

  $validResponse = md5("{$A1}:{$digestParts['nonce']}:{$digestParts['nc']}:{$digestParts['cnonce']}:{$digestParts['qop']}:{$A2}");
  if ($digestParts['response']!=$validResponse) requireLogin($realm,$nonce);

  // We're in!
  //echo 'Well done sir, you made it all the way through the login!';

// This function returns the digest string
function getDigest() {
  $digest = '';
  // mod_php
  if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
    $digest = $_SERVER['PHP_AUTH_DIGEST'];
  // most other servers
  elseif (isset($_SERVER['HTTP_AUTHENTICATION'])) {
    if (strpos(strtolower($_SERVER['HTTP_AUTHENTICATION']),'digest')===0)
      $digest = substr($_SERVER['HTTP_AUTHORIZATION'], 7);

  return $digest;

// This function forces a login prompt
function requireLogin($realm, $nonce) {
    $cabecalho = 'WWW-Authenticate: Digest realm="' . $realm . '",'.
                 ' qop="auth", nonce="' . $nonce . '", '.
                 'opaque="' . md5($realm) . '"';
    header('HTTP/1.0 401 Unauthorized');
    echo 'Cancelado';

// This function extracts the separate values from the digest string
function digestParse($digest) {
    // protect against missing data
    $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
    $data = array();

    preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $digest, $matches, PREG_SET_ORDER);

    foreach ($matches as $m) {
        $data[$m[1]] = $m[2] ? $m[2] : $m[3];

    return $needed_parts ? false : $data;

//Analyse 401 header got from server and makes the parameters to
//setCredentials method of nusoap client
function getDigestToServer($url) //Used by client.php script, above
  //Try to open the URL (read-only) - we are expecting this to fail because it is in the secured area
  $fp = @fopen($url, 'r');

  // Check response header from the server
  if (isset($http_response_header))
      // is it the 401 error we are expecting?
      if (preg_match("@HTTP/[\d\.]+ 401@", $http_response_header[0]))
          // recover the digest parameter string
          for ($i = count( $http_response_header ) - 1; $i >= 0; $i-- )
              if (strncasecmp('WWW-Authenticate', $http_response_header[$i], 16 ) == 0 )
                  $wauth = $http_response_header[$i];
                  $wauth = preg_replace("/^.+Digest /","",$wauth);
                  $wauthkeys = explode(",",$wauth);
                  $dgheaders = array();
                  foreach($wauthkeys as $seg) {
                     list($key,$val) = explode("=",$seg);
                     $val = preg_replace("/\"/","",$val);
                     $dgheaders[trim($key)] = $val;
                  return $dgheaders;
          die( 'Error connecting: Não encontrado "WWW-Authenticate"');
          die( '2-Error connecting: ' . $http_response_header[0]);
      die( '3-Error connecting: Bad URL, timeout, etc.');
View user's profileFind all posts by bene20Send private message
Client-server digest authentication example
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT - 5 Hours  
Page 1 of 1  

 Reply to topic