2929<![CDATA[
3030<?php
3131if (!isset($_SERVER['PHP_AUTH_USER'])) {
32+ header('HTTP/1.1 401 Unauthorized');
3233 header('WWW-Authenticate: Basic realm="My Realm"');
33- header('HTTP/1.0 401 Unauthorized');
3434 echo 'Text to send if user hits Cancel button';
3535 exit;
3636} else {
@@ -44,13 +44,13 @@ if (!isset($_SERVER['PHP_AUTH_USER'])) {
4444 </para >
4545
4646 <note >
47- <title >Compatibility Note </title >
47+ <title >Compatibility</title >
4848 <para >
4949 Please be careful when coding the HTTP header lines. In order to guarantee maximum
5050 compatibility with all clients, the keyword "Basic" should be written with an
5151 uppercase "B", the realm string must be enclosed in double (not single) quotes,
5252 and exactly one space should precede the <emphasis >401</emphasis > code in the
53- <emphasis >HTTP/1.0 401</emphasis > header line. Authentication parameters have
53+ <emphasis >HTTP/1.1 401</emphasis > header line. Authentication parameters have
5454 to be comma-separated.
5555 </para >
5656 </note >
@@ -63,16 +63,8 @@ if (!isset($_SERVER['PHP_AUTH_USER'])) {
6363 user in a dbm file.
6464 </para >
6565
66- <para >
67- Watch out for buggy Internet Explorer browsers out there. They
68- seem very picky about the order of the headers. Sending the
69- <emphasis >WWW-Authenticate</emphasis > header before the
70- <literal >HTTP/1.0 401</literal > header seems to do the trick
71- for now.
72- </para >
73-
7466 <note >
75- <title >Configuration Note </title >
67+ <title >Apache Configuration </title >
7668 <para >
7769 PHP uses the presence of an <literal >AuthType</literal > directive
7870 to determine whether external authentication is in effect.
@@ -84,65 +76,32 @@ if (!isset($_SERVER['PHP_AUTH_USER'])) {
8476 controls a non-authenticated URL from stealing passwords from
8577 authenticated URLs on the same server.
8678 </simpara >
87- <simpara >
88- Both Netscape Navigator and Internet Explorer will clear the local browser
89- window's authentication cache for the realm upon receiving a
90- server response of 401. This can effectively "log out" a user,
91- forcing them to re-enter their username and password. Some people
92- use this to "time out" logins, or provide a "log-out" button.
93- </simpara >
94- <para >
95- <example >
96- <title >HTTP Authentication example forcing a new name/password</title >
97- <programlisting role =" php" >
98- <![CDATA[
99- <?php
100- function authenticate() {
101- header('WWW-Authenticate: Basic realm="Test Authentication System"');
102- header('HTTP/1.0 401 Unauthorized');
103- echo "You must enter a valid login ID and password to access this resource\n";
104- exit;
105- }
106-
107- if (!isset($_SERVER['PHP_AUTH_USER']) ||
108- ($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
109- authenticate();
110- } else {
111- echo "<p>Welcome: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
112- echo "Old: " . htmlspecialchars($_REQUEST['OldAuth']);
113- echo "<form action='' method='post'>\n";
114- echo "<input type='hidden' name='SeenBefore' value='1' />\n";
115- echo "<input type='hidden' name='OldAuth' value=\"" . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "\" />\n";
116- echo "<input type='submit' value='Re Authenticate' />\n";
117- echo "</form></p>\n";
118- }
119- ?>
120- ]]>
121- </programlisting >
122- </example >
123- </para >
124- <simpara >
125- This behavior is not required by the <literal >HTTP Basic</literal >
126- authentication standard, so you should never depend on this. Testing with
127- <literal >Lynx</literal > has shown that <literal >Lynx</literal > does not clear
128- the authentication credentials with a 401 server response, so pressing back
129- and then forward again will open the resource as long as the credential
130- requirements haven't changed. The user can press the
131- <literal >'_'</literal > key to clear their authentication information, however.
132- </simpara >
133- <simpara >
134- In order to get HTTP Authentication to work using IIS server with the CGI version
135- of PHP you must edit your IIS configuration "<literal >Directory Security</literal >".
136- Click on "<literal >Edit</literal >" and only check
137- "<literal >Anonymous Access</literal >", all other fields
138- should be left unchecked.
139- </simpara >
79+
80+ <note >
81+ <title >Browser behavior</title >
82+ <simpara >
83+ HTTP Basic authentication really is basic, and it wasn't designed to support
84+ logouts. Because HTTP is a stateless protocol, most browsers will cache the
85+ provided credentials as soon as a <literal >2xx</literal > status code is seen,
86+ and will send them in every request, until the browser is closed. There is no
87+ defined way for a server to request a new prompt for credentials.
88+
89+ Over the years, various workarounds for this have spread as advice on the internet,
90+ but they all depend on how different browsers have chosen to handle undefined edge
91+ cases (or even violations of the HTTP standard). It is best to avoid such
92+ workarounds and not use Basic authentication for anything serious.
93+ </simpara >
94+ </note >
95+
14096 <note >
141- <title >IIS Note: </title >
97+ <title >IIS Configuration </title >
14298 <simpara >
143- For HTTP Authentication to work with IIS, the PHP directive
144- <link linkend =" ini.cgi.rfc2616-headers" >cgi.rfc2616_headers</link > must
145- be set to <literal >0</literal > (the default value).
99+ In order to get HTTP Authentication to work on IIS server with the CGI version of
100+ PHP, the php.ini directive <link linkend =" ini.cgi.rfc2616-headers" >cgi.rfc2616_headers</link >
101+ must be set to <literal >0</literal > (the default value), and you must edit your IIS
102+ configuration "<literal >Directory Security</literal >".
103+ Click on "<literal >Edit</literal >" and only check "<literal >Anonymous Access</literal >",
104+ all other fields should be left unchecked.
146105 </simpara >
147106 </note >
148107
0 commit comments