-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathhttp-auth.xml
238 lines (212 loc) · 8.76 KB
/
http-auth.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: dec1f8445ab2af7fbafef012fb7907ab2cd349b5 Maintainer: pastore Status: ready -->
<!-- CREDITS: matteobug,cortesi,cucinato -->
<chapter xml:id="features.http-auth" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Autenticazione HTTP usando PHP</title>
<simpara>
È possibile usare la
funzione <function>header</function> per inviare un messaggio di <literal>"Authentication Required"</literal>
al browser dell'utente, provocando quindi l'apertura di una finestra contenente una richiesta di
Nome utente/Password. Una volta che l'utente ha compilato i campi nome utente e password,
l'URL contenente lo script PHP verrà richiamato nuovamente usando le
<link linkend="reserved.variables">variabili predefinite</link>,
<varname>PHP_AUTH_USER</varname>, <varname>PHP_AUTH_PW</varname> e
<varname>AUTH_TYPE</varname> impostate con nome, password e
tipo di autenticazione. Queste variabili predefinite possono essere trovate
nell'array <varname>$_SERVER</varname>. Saranno supportati entrambi i
metodi di autenticazione, "Basic" e "Digest" (a partire dal PHP 5.1.0).
Fare riferimento alla funzione <function>header</function> per ulteriori informazioni.
</simpara>
<para>
Un frammento di script di esempio che richiede l'autenticazione da parte del browser
su una pagina, potrebbe essere il seguente:
</para>
<para>
<example>
<title>Esempio di Autenticazione HTTP "Basic"</title>
<programlisting role="php">
<![CDATA[
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Il mio realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Messaggio da inviare se si preme il tasto Cancel';
exit;
} else {
echo "<p>Ciao {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>Hai inserito {$_SERVER['PHP_AUTH_PW']} come tua password.</p>";
}
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>Esempio di autenticazione HTTP "Digest"</title>
<para>
Questo esempio illustra come implementare una autenticazione
Digest. Per maggiori dettagli vedere <link
xlink:href="&url.rfc;2617">RFC 2617</link>.
</para>
<programlisting role="php">
<![CDATA[
<?php
$realm = 'Restricted area';
//user => password
$users = array('admin' => 'mypass', 'guest' => 'guest');
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Text to send if user hits Cancel button');
}
// analisi della variabile PHP_AUTH_DIGEST
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset($users[$data['username']]))
die('Wrong Credentials!');
// generazione di una risposta valida
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response)
die('Wrong Credentials!');
// Ok, utente/password validi
echo 'Your are logged in as: ' . $digest['username'];
// funzione che analizza l'header http auth
function http_digest_parse($txt)
{
// protezione contro i dati mancanti
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($needed_parts));
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<title>Note sulla compatibilità</title>
<para>
Fare molta attenzione quando si scrive codice per le intestazioni HTTP. Per ottenere la massima
compatibilità con tutti i client, la parola-chiave "Basic" deve essere scritta con una
"B" maiuscola, la stringa realm deve essere racchiusa in virgolette doppie (non singole),
ed esattamente uno spazio deve precedere il codice <emphasis>401</emphasis> nella linea
di intestazione <emphasis>HTTP/1.0 401</emphasis>. I parametri di autenticazione devono
essere separati da virgole come si vede nell'esempio qui sopra.
</para>
</note>
<para>
Invece di stampare semplicemente <varname>PHP_AUTH_USER</varname> e
<varname>PHP_AUTH_PW</varname>, 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.
</para>
<para>
Si faccia attenzione ad alcune versioni di Internet Explorer. Sembra
che siano molto schizzinosi riguardo all'ordine delle intestazioni. Inviare l'intestazione
<emphasis>WWW-Authenticate</emphasis> prima dell'intestazione
<literal>HTTP/1.0 401</literal> sembra sistemare le cose per
il momento.
</para>
<note>
<title>Nota sulla Configurazione</title>
<para>
PHP usa la presenza di una direttiva <literal>AuthType</literal>
per determinare se viene utilizzata l'autenticazione esterna.
</para>
</note>
<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.
</simpara>
<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 "log out" per l'utente,
che lo forza a reinserire lo username e la password. Alcune persone
usano questo per fare il "time out" dei login, o per rendere disponibili bottoni di "log-out".
</simpara>
<para>
<example>
<title>Esempio di Autenticazione HTTP che impone l'inserimento di nuovo username/password</title>
<programlisting role="php">
<![CDATA[
<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Prova del Sistema di Autenticazione"');
header('HTTP/1.0 401 Unauthorized');
echo "Per poter accedere a questa risorsa occorre inserire una coppia login e password valide\n";
exit;
}
if (!isset($_SERVER['PHP_AUTH_USER']) ||
($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
} else {
echo "<p>Benvenuto: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
echo "Vecchio: " . htmlspecialchars($_REQUEST['OldAuth']);
echo "<form action='' method='post'>\n";
echo "<input type='hidden' name='SeenBefore' value='1' />\n";
echo "<input type='hidden' name='OldAuth' value=\"" . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "\" />\n";
echo "<input type='submit' value='Ri autentifica' />\n";
echo "</form></p>\n";
}
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Questo comportamento non è richiesto dallo standard di autenticazione HTTP
Basic, quindi non si dovrebbe mai fare affidamento su di esso. Test effettuati con
<literal>Lynx</literal> mostrano che <literal>Lynx</literal> 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'utente può però premere il
tasto '_' al fine di cancellare le sue informazioni di autenticazione.
</simpara>
<simpara>
Al fine di far funzionare l'Autenticazione HTTP usando il server IIS con la versione CGI
di PHP si deve modificare la configurazione di IIS "<literal>Directory Security</literal>".
Cliccare su "<literal>Edit</literal>" e selezionare solo
"<literal>Anonymous Access</literal>", tutti gli altri campi
devono essere lasciati deselezionati.
</simpara>
<note>
<title>Nota su IIS:</title>
<simpara>
Al fine di fare funzionare la Autenticazione HTTP con IIS, la direttiva PHP
<link linkend="ini.cgi.rfc2616-headers">cgi.rfc2616_headers</link> deve
essere impostata al valore <literal>0</literal> (il valore predefinito).
</simpara>
</note>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->