<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/features.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'it',
  ),
  'this' => 
  array (
    0 => 'features.http-auth.php',
    1 => 'Autenticazione HTTP usando PHP',
    2 => 'Autenticazione HTTP usando PHP',
  ),
  'up' => 
  array (
    0 => 'features.php',
    1 => 'Caratteristiche',
  ),
  'prev' => 
  array (
    0 => 'features.php',
    1 => 'Caratteristiche',
  ),
  'next' => 
  array (
    0 => 'features.cookies.php',
    1 => 'Cookies',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'it',
    'path' => 'features/http-auth.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="features.http-auth" class="chapter">
  <h1 class="title">Autenticazione HTTP usando PHP</h1>


  <p class="simpara">
   È possibile usare la
   funzione <span class="function"><a href="function.header.php" class="function">header()</a></span> per inviare un messaggio di <code class="literal">&quot;Authentication Required&quot;</code>
   al browser dell&#039;utente, provocando quindi l&#039;apertura di una finestra contenente una richiesta di
   Nome utente/Password. Una volta che l&#039;utente ha compilato i campi nome utente e password,
   l&#039;URL contenente lo script PHP verrà richiamato nuovamente usando le
   <a href="reserved.variables.php" class="link">variabili predefinite</a>,
   <var class="varname">PHP_AUTH_USER</var>, <var class="varname">PHP_AUTH_PW</var> e
   <var class="varname">AUTH_TYPE</var> impostate con nome, password e
   tipo di autenticazione. Queste variabili predefinite possono essere trovate
   nell&#039;array <var class="varname"><a href="reserved.variables.server.php" class="classname">$_SERVER</a></var>. Saranno supportati entrambi i
   metodi di autenticazione, &quot;Basic&quot; e &quot;Digest&quot; (a partire dal PHP 5.1.0).
   Fare riferimento alla funzione <span class="function"><a href="function.header.php" class="function">header()</a></span> per ulteriori informazioni.
  </p>

  <p class="para">
   Un frammento di script di esempio che richiede l&#039;autenticazione da parte del browser
   su una pagina, potrebbe essere il seguente:
  </p>
  <p class="para">
   <div class="example" id="example-1">
    <p><strong>Example #1 Esempio di Autenticazione HTTP &quot;Basic&quot;</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">if (!isset(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">])) {<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'WWW-Authenticate: Basic realm="Il mio realm"'</span><span style="color: #007700">);<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'HTTP/1.0 401 Unauthorized'</span><span style="color: #007700">);<br />    echo </span><span style="color: #DD0000">'Messaggio da inviare se si preme il tasto Cancel'</span><span style="color: #007700">;<br />    exit;<br />} else {<br />    echo </span><span style="color: #DD0000">"&lt;p&gt;Ciao </span><span style="color: #007700">{</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">]}</span><span style="color: #DD0000">.&lt;/p&gt;"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"&lt;p&gt;Hai inserito </span><span style="color: #007700">{</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_PW'</span><span style="color: #007700">]}</span><span style="color: #DD0000"> come tua password.&lt;/p&gt;"</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </p>

  <p class="para">
   <div class="example" id="example-2">
    <p><strong>Example #2 Esempio di autenticazione HTTP &quot;Digest&quot;</strong></p>
    <div class="example-contents"><p>
     Questo esempio illustra come implementare una autenticazione
     Digest. Per maggiori dettagli vedere <a href="https://datatracker.ietf.org/doc/html/rfc2617" class="link external">&raquo;&nbsp;RFC 2617</a>.
    </p></div>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$realm </span><span style="color: #007700">= </span><span style="color: #DD0000">'Restricted area'</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">//user =&gt; password<br /></span><span style="color: #0000BB">$users </span><span style="color: #007700">= array(</span><span style="color: #DD0000">'admin' </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'mypass'</span><span style="color: #007700">, </span><span style="color: #DD0000">'guest' </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'guest'</span><span style="color: #007700">);<br /><br /><br />if (empty(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_DIGEST'</span><span style="color: #007700">])) {<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'HTTP/1.1 401 Unauthorized'</span><span style="color: #007700">);<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'WWW-Authenticate: Digest realm="'</span><span style="color: #007700">.</span><span style="color: #0000BB">$realm</span><span style="color: #007700">.<br />           </span><span style="color: #DD0000">'",qop="auth",nonce="'</span><span style="color: #007700">.</span><span style="color: #0000BB">uniqid</span><span style="color: #007700">().</span><span style="color: #DD0000">'",opaque="'</span><span style="color: #007700">.</span><span style="color: #0000BB">md5</span><span style="color: #007700">(</span><span style="color: #0000BB">$realm</span><span style="color: #007700">).</span><span style="color: #DD0000">'"'</span><span style="color: #007700">);<br /><br />    die(</span><span style="color: #DD0000">'Text to send if user hits Cancel button'</span><span style="color: #007700">);<br />}<br /><br /><br /></span><span style="color: #FF8000">// analisi della variabile PHP_AUTH_DIGEST<br /></span><span style="color: #007700">if (!(</span><span style="color: #0000BB">$data </span><span style="color: #007700">= </span><span style="color: #0000BB">http_digest_parse</span><span style="color: #007700">(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_DIGEST'</span><span style="color: #007700">])) ||<br />    !isset(</span><span style="color: #0000BB">$users</span><span style="color: #007700">[</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'username'</span><span style="color: #007700">]]))<br />    die(</span><span style="color: #DD0000">'Wrong Credentials!'</span><span style="color: #007700">);<br /><br /><br /></span><span style="color: #FF8000">// generazione di una risposta valida<br /></span><span style="color: #0000BB">$A1 </span><span style="color: #007700">= </span><span style="color: #0000BB">md5</span><span style="color: #007700">(</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'username'</span><span style="color: #007700">] . </span><span style="color: #DD0000">':' </span><span style="color: #007700">. </span><span style="color: #0000BB">$realm </span><span style="color: #007700">. </span><span style="color: #DD0000">':' </span><span style="color: #007700">. </span><span style="color: #0000BB">$users</span><span style="color: #007700">[</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'username'</span><span style="color: #007700">]]);<br /></span><span style="color: #0000BB">$A2 </span><span style="color: #007700">= </span><span style="color: #0000BB">md5</span><span style="color: #007700">(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'REQUEST_METHOD'</span><span style="color: #007700">].</span><span style="color: #DD0000">':'</span><span style="color: #007700">.</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'uri'</span><span style="color: #007700">]);<br /></span><span style="color: #0000BB">$valid_response </span><span style="color: #007700">= </span><span style="color: #0000BB">md5</span><span style="color: #007700">(</span><span style="color: #0000BB">$A1</span><span style="color: #007700">.</span><span style="color: #DD0000">':'</span><span style="color: #007700">.</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'nonce'</span><span style="color: #007700">].</span><span style="color: #DD0000">':'</span><span style="color: #007700">.</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'nc'</span><span style="color: #007700">].</span><span style="color: #DD0000">':'</span><span style="color: #007700">.</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'cnonce'</span><span style="color: #007700">].</span><span style="color: #DD0000">':'</span><span style="color: #007700">.</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'qop'</span><span style="color: #007700">].</span><span style="color: #DD0000">':'</span><span style="color: #007700">.</span><span style="color: #0000BB">$A2</span><span style="color: #007700">);<br /><br />if (</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'response'</span><span style="color: #007700">] != </span><span style="color: #0000BB">$valid_response</span><span style="color: #007700">)<br />    die(</span><span style="color: #DD0000">'Wrong Credentials!'</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// Ok, utente/password validi<br /></span><span style="color: #007700">echo </span><span style="color: #DD0000">'Your are logged in as: ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$digest</span><span style="color: #007700">[</span><span style="color: #DD0000">'username'</span><span style="color: #007700">];<br /><br /><br /></span><span style="color: #FF8000">// funzione che analizza l'header http auth<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">http_digest_parse</span><span style="color: #007700">(</span><span style="color: #0000BB">$txt</span><span style="color: #007700">)<br />{<br />    </span><span style="color: #FF8000">// protezione contro i dati mancanti<br />    </span><span style="color: #0000BB">$needed_parts </span><span style="color: #007700">= array(</span><span style="color: #DD0000">'nonce'</span><span style="color: #007700">=&gt;</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #DD0000">'nc'</span><span style="color: #007700">=&gt;</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #DD0000">'cnonce'</span><span style="color: #007700">=&gt;</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #DD0000">'qop'</span><span style="color: #007700">=&gt;</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #DD0000">'username'</span><span style="color: #007700">=&gt;</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #DD0000">'uri'</span><span style="color: #007700">=&gt;</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #DD0000">'response'</span><span style="color: #007700">=&gt;</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />    </span><span style="color: #0000BB">$data </span><span style="color: #007700">= array();<br />    </span><span style="color: #0000BB">$keys </span><span style="color: #007700">= </span><span style="color: #0000BB">implode</span><span style="color: #007700">(</span><span style="color: #DD0000">'|'</span><span style="color: #007700">, </span><span style="color: #0000BB">array_keys</span><span style="color: #007700">(</span><span style="color: #0000BB">$needed_parts</span><span style="color: #007700">));<br /><br />    </span><span style="color: #0000BB">preg_match_all</span><span style="color: #007700">(</span><span style="color: #DD0000">'@(' </span><span style="color: #007700">. </span><span style="color: #0000BB">$keys </span><span style="color: #007700">. </span><span style="color: #DD0000">')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@'</span><span style="color: #007700">, </span><span style="color: #0000BB">$txt</span><span style="color: #007700">, </span><span style="color: #0000BB">$matches</span><span style="color: #007700">, </span><span style="color: #0000BB">PREG_SET_ORDER</span><span style="color: #007700">);<br /><br />    foreach (</span><span style="color: #0000BB">$matches </span><span style="color: #007700">as </span><span style="color: #0000BB">$m</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #0000BB">$m</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">]] = </span><span style="color: #0000BB">$m</span><span style="color: #007700">[</span><span style="color: #0000BB">3</span><span style="color: #007700">] ? </span><span style="color: #0000BB">$m</span><span style="color: #007700">[</span><span style="color: #0000BB">3</span><span style="color: #007700">] : </span><span style="color: #0000BB">$m</span><span style="color: #007700">[</span><span style="color: #0000BB">4</span><span style="color: #007700">];<br />        unset(</span><span style="color: #0000BB">$needed_parts</span><span style="color: #007700">[</span><span style="color: #0000BB">$m</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">]]);<br />    }<br /><br />    return </span><span style="color: #0000BB">$needed_parts </span><span style="color: #007700">? </span><span style="color: #0000BB">false </span><span style="color: #007700">: </span><span style="color: #0000BB">$data</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </p>

  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <strong>Note sulla compatibilità</strong><br />
   <p class="para">
    Fare molta attenzione quando si scrive codice per le intestazioni HTTP. Per ottenere la  massima
    compatibilità con tutti i client, la parola-chiave &quot;Basic&quot; deve essere scritta con una
    &quot;B&quot; maiuscola, la stringa realm deve essere racchiusa in virgolette doppie (non singole),
    ed esattamente uno spazio deve precedere il codice <em>401</em> nella linea
    di intestazione <em>HTTP/1.0 401</em>. I parametri di autenticazione devono
    essere separati da virgole come si vede nell&#039;esempio qui sopra.
   </p>
  </p></blockquote>

  <p class="para">
   Invece di stampare semplicemente <var class="varname">PHP_AUTH_USER</var> e
   <var class="varname">PHP_AUTH_PW</var>, probabilmente si vorrà controllare
   la validità dello username e della password.
   Probabilmente inviando una chiamata al database,
   o cercando un utente in un file dbm.
  </p>

  <p class="para">
   Si faccia attenzione ad alcune versioni di Internet Explorer. Sembra
   che siano molto schizzinosi riguardo all&#039;ordine delle intestazioni. Inviare l&#039;intestazione
   <em>WWW-Authenticate</em> prima dell&#039;intestazione
   <code class="literal">HTTP/1.0 401</code> sembra sistemare le cose per
   il momento.
  </p>

  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <strong>Nota sulla Configurazione</strong><br />
   <p class="para">
    PHP usa la presenza di una direttiva <code class="literal">AuthType</code>
    per determinare se viene utilizzata l&#039;autenticazione esterna.
   </p>
  </p></blockquote>

  <p class="simpara">
   Si fa notare, però, che quanto scritto sopra non impedisce a qualcuno che
   controlla un URL non autenticato di sottrarre password da
   URL autenticati presenti sullo stesso server.
  </p>
  <p class="simpara">
   Sia Netscape Navigator che Internet Explorer cancellano la cache locale
   della finestra del browser, per quanto riguarda il realm, al ricevimento
   di una risposta 401 da parte del server. Questo è effettivamente un meccanismo di &quot;log out&quot; per l&#039;utente,
   che lo forza a reinserire lo username e la password. Alcune persone
   usano questo per fare il &quot;time out&quot; dei login, o per rendere disponibili bottoni di &quot;log-out&quot;.
  </p>
  <p class="para">
   <div class="example" id="example-3">
    <p><strong>Example #3 Esempio di Autenticazione HTTP che impone l&#039;inserimento di nuovo username/password</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">authenticate</span><span style="color: #007700">() {<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'WWW-Authenticate: Basic realm="Prova del Sistema di Autenticazione"'</span><span style="color: #007700">);<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'HTTP/1.0 401 Unauthorized'</span><span style="color: #007700">);<br />    echo </span><span style="color: #DD0000">"Per poter accedere a questa risorsa occorre inserire una coppia login e password valide\n"</span><span style="color: #007700">;<br />    exit;<br />}<br /> <br />if (!isset(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">]) ||<br />    (</span><span style="color: #0000BB">$_POST</span><span style="color: #007700">[</span><span style="color: #DD0000">'SeenBefore'</span><span style="color: #007700">] == </span><span style="color: #0000BB">1 </span><span style="color: #007700">&amp;&amp; </span><span style="color: #0000BB">$_POST</span><span style="color: #007700">[</span><span style="color: #DD0000">'OldAuth'</span><span style="color: #007700">] == </span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">])) {<br />    </span><span style="color: #0000BB">authenticate</span><span style="color: #007700">();<br />} else {<br />    echo </span><span style="color: #DD0000">"&lt;p&gt;Benvenuto: " </span><span style="color: #007700">. </span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">]) . </span><span style="color: #DD0000">"&lt;br /&gt;"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"Vecchio: " </span><span style="color: #007700">. </span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$_REQUEST</span><span style="color: #007700">[</span><span style="color: #DD0000">'OldAuth'</span><span style="color: #007700">]);<br />    echo </span><span style="color: #DD0000">"&lt;form action='' method='post'&gt;\n"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"&lt;input type='hidden' name='SeenBefore' value='1' /&gt;\n"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"&lt;input type='hidden' name='OldAuth' value=\"" </span><span style="color: #007700">. </span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">]) . </span><span style="color: #DD0000">"\" /&gt;\n"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"&lt;input type='submit' value='Ri autentifica' /&gt;\n"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"&lt;/form&gt;&lt;/p&gt;\n"</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </p>
  <p class="simpara">
   Questo comportamento non è richiesto dallo standard di autenticazione HTTP
   Basic, quindi non si dovrebbe mai fare affidamento su di esso. Test effettuati con
   <code class="literal">Lynx</code> mostrano che <code class="literal">Lynx</code> non cancella
   le credenziali di autenticazione al ricevimento del codice di risposta 401 da parte del server, quindi, premendo indietro
   e avanti nuovamente, darà nuovamente accesso alla risorsa, ammesso che le rispettive richieste
   di credenziali non siano cambiate. L&#039;utente può però premere il
   tasto &#039;_&#039; al fine di cancellare le sue informazioni di autenticazione.
  </p>
  <p class="simpara">
   Al fine di far funzionare l&#039;Autenticazione HTTP usando il server IIS con la versione CGI
   di PHP si deve modificare la configurazione di IIS &quot;<code class="literal">Directory Security</code>&quot;.
   Cliccare su &quot;<code class="literal">Edit</code>&quot; e selezionare solo
   &quot;<code class="literal">Anonymous Access</code>&quot;, tutti gli altri campi
   devono essere lasciati deselezionati.
  </p>
  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <strong>Nota su IIS:</strong><br />
   <span class="simpara">
    Al fine di fare funzionare la Autenticazione HTTP con IIS, la direttiva PHP
    <a href="ini.core.php#ini.cgi.rfc2616-headers" class="link">cgi.rfc2616_headers</a> deve
    essere impostata al valore <code class="literal">0</code> (il valore predefinito).
   </span>
  </p></blockquote>

 </div>
<?php manual_footer($setup); ?>