User Contributed Notes HTTP authenticatie met PHP |
add a note |
fredrick-realm at home dot com
21-Jul-1999 10:02 |
|
A few notes on authentication in which it's possible I overlooked some
things. Considering a prior post about using the same salt for all users
so you can match passwords; I think it would be better to not do so, as
you can figure out the salt from the password and match. (Example, salt
in DES if I'm not mistaken is the first 2 characters)
Something I've
been trying to figure out is secure apache module PHP on a multi-user
server.
Delima (with postgres)- any user can write a PHP page to
read another users databases. Set your database to connect using username
and password, and any user can read your username and password from
wherever you place them. (use PHP function to read it and as it has to be
readable by your web process for you to read it, they can)
The
closest I've come to a solution for this is to run php as a CGI module
with suexec or cgiwrap.
Hopefuly someone else has a better
solution; otherwise, something to think about before you think of your
databases as being secure with php interfacing to them.
|
|
auke at muze dot nl
18-Dec-1999 01:42 |
|
Someone gave me a simple solution to the 'logout' problem: add some sort of
timestamp to the basic realm you send in the WWW_Authenticate header. Mine
now is: $realm="RealmName (
".strftime("%c",time())." )";. (btw: the problem
was: 1) IE4 asks for the page one more time after a 401, defeating sending
a 401 once to force a user to log on again. and 2) IE4 remembers the
password, and puts it default in the logon window. Changing the realm
solves these problems, not the 'logon failed' message of NS though).
|
|
rratboy at pobox dot com
09-Feb-2000 06:59 |
|
I had the same problem as above (that is, with apache I can't get the auth
info). The solution I found goes like this:
$headers =
getallheaders();
$auth=$headers[authorization];
if ($auth=='') {
$auth=$headers[Authorization];
}
if($auth=='')
{
Header("WWW-Authenticate: Basic
realm=\"$PROG_NAME\"");
Header("HTTP/1.0 401
Unauthorized");
}
list($user, $pass) =
explode(":", base64_decode(substr($auth, 6)));
|
|
tigran at freenet dot am
19-May-2000 09:31 |
|
Here is a code for the public sites enabling both logout bottom and timeout
using php+mysql. Working for both browsers.
The part
"required" for each user protected
page:
<?
function auth () {
Header("WWW-Authenticate: Basic realm=\"ArmFN public
site\"");
Header("HTTP/1.0 401
Unauthorized");
echo "You have to authentificate
yourself first \n";
exit;
}
mysql_connect("localhost","train","")
or die("Unable to connect to SQL server");
mysql_select_db(
"train") or die( "Unable to select database");
if(!isset($PHP_AUTH_USER)) {
$timeout =
mktime(date(G),date(i)+10,0,date("m"),date("d"),date("Y"));
mysql_query("update
users set login='$timeout' where id='$user' and pasw='$pass'") or
die("k");
auth();
} else {
$pass = $PHP_AUTH_PW;
$user = $PHP_AUTH_USER;
$nowtime =
mktime(date(G),date(i),0,date("m"),date("d"),date("Y"));
$quer2
= mysql_query("select * from users where id='$user' and pasw='$pass'
and login > '$nowtime'") or die("kuk2");
if
(mysql_num_rows($quer2) == "0") {
$timeout =
mktime(date(G),date(i)+10,0,date("m"),date("d"),date("Y"));
mysql_query("update
users set login='$timeout' where id='$user' and pasw='$pass'") or
die("k");
auth();
}
}
?>
You
can have a "logout" bottom with hidden $go="logout"
form element and then have somewhere this part:
if ($do ==
"logout")
{
mysql_connect("localhost","train","")
or die("Unable to connect to SQL server");
mysql_select_db(
"train") or die( "Unable to select database");
mysql_query("update users set login=0 where id='$PHP_AUTH_USER'
and pasw='$PHP_AUTH_PW'") or die("k");
}
|
|
owld at mail dot ru
30-Aug-2000 10:04 |
|
Good day.I've solved a problem where IE4 asks for the age one more time
after a 401, defeating sending a 401 once to force a user to log on
again.
function authenticate() {
setcookie("noauth","");
Header(
"WWW-authenticate: Basic realm=\"test\"");
Header( "HTTP/1.0 401 Unauthorized");
echo "You must
enter user name";
exit ;
}
if (
!isset($PHP_AUTH_USER) || ($logoff==1) &&
$noauth=="yes" ) {
authenticate();
}
And logoff link -
<a
href="samehtml.phtml?logoff=1">Logoff</a></td>
Dmitry
Alyekhin
|
|
marcel at humanique dot com
16-Oct-2000 10:01 |
|
The new Mozilla browser doesn't seem to like the switched authentication
lines.
This doesn't work (I have build
2000101308):
Header( "WWW-authenticate: Basic
realm=\"test\"");
Header( "HTTP/1.0 401
Unauthorized");
The first time you authenticate all seems
ok, but the second time it always returns unauthorized.
This
works as it should:
Header( "HTTP/1.0 401
Unauthorized");
Header( "WWW-authenticate: Basic
realm=\"test\"");
|
|
yasuo_ohgaki at hotmail dot com
10-Mar-2001 09:19 |
|
I suggest to read RFC2617 (HTTP Authentication: Basic and Digest Access
Authentication) and related RFCs.
|
|
k u d o s at t e l u s p l a n e t dot n e t
05-Apr-2001 06:19 |
|
Thanks to [email protected] for the rfc note needed to solve this
one. This looks like it flushed out the authentication headers on both
Netscape and IE:
Header("WWW-Authenticate: Basic
realm=\"Whatever Realm\", stale=FALSE");
|
|
philip at cornado dot com
17-May-2001 10:55 |
|
You may enjoy this tutorial :
|
|
eezyeee at yahoo dot com
12-Jun-2001 10:53 |
|
This is a good resource for setting up htaccess schemes:
The
windows version of apache comes with htpasswd.exe in the apache\bin
directory.
The only thing that present problems is you have to
change your .htaccess file to point to the created password file (ie
C:\directory\passwords.file)....so if you transfer the file back to a *nix
server it wont find your file.
One (temporary) workaround is
changing your local httpd.conf file to point to a different access
file:
AccessFileName htaccess.
You just have to make
sure to syncronize your access files.
Im not sure if you can
point your htaccess to two password files??
AuthName "restricted
stuff"
AuthType Basic
AuthUserFile
/usr/local/etc/httpd/users
AuthUserFile
C:\directory\password.file
require valid-user
|
|
jonhaynes at bigfoot dot com
28-Jan-2002 06:25 |
|
Restrict access by username, password AND ip
address:
<? function authenticate()
{ header("WWW-Authenticate: Basic
realm=\":-!\""); header("HTTP/1.0 401
Unauthorized"); print("You must enter a valid login username
and password to access this
resource.\n"); exit; } if(!isset($PHP_AUTH_USER)){
authenticate(); } else
{ $c=mysql_pconnect("server.name","user","password"); mysql_select_db("dbname",$c); $q=sprintf("SELECT
username,password FROM authenticateTable WHERE username='%s' AND
password=PASSWORD('%s') AND
ipaddress='%s'", $PHP_AUTH_USER,$PHP_AUTH_PW,$REMOTE_ADDR); $q=mysql_query($q); if(mysql_num_rows($q)==0){
authenticate(); } } ?>
|
|
sjeffrey at inquesis dot com
29-Jan-2002 10:00 |
|
To get it to work with IIS try using this code before setting your
"$auth = 0" and the "if (isset($PHP_AUTH_USER) &&
isset($PHP_AUTH_PW))"
//////////////////////////////////////////
if
($PHP_AUTH_USER == "" && PHP_AUTH_PW == ""
&& ereg("^Basic ", $HTTP_AUTHORIZATION)) {
list($PHP_AUTH_USER, $PHP_AUTH_PW) = explode(":",
base64_decode(substr($HTTP_AUTHORIZATION, 6)));
}
//////////////////////////////////////////
It worked
for me on IIS 5 and PHP 4 in ISAPI
|
|
lenny at phpkingdom dot com
22-Feb-2002 07:09 |
|
I tried the method posted by [email protected] for a logout feature,
which seems to be a problem for users of http authentication. Tigran's
method is perfect, except that after you log out, you can STILL access the
pages by clicking on "cancel" when prompted again by the Java
window. This will trigger the 401 error. But it will also create an
entry in the history folder.
You will notice the
"forward" button on your browser becomes clickable. You only
have to click on the that "forward" button to be able to access
the protected pages.
I have found a solution for this problem by
using a little Javascript to refresh to another page.
Please go to
my website for details:
|
|
louis dot carlier at ngroups dot com
24-May-2002 03:22 |
|
The definitive HTTP authorization code:
function
login_error() { echo "error - login process
failed." }
if (!isset($PHP_AUTH_USER)) {
header("WWW-Authenticate: Basic realm=\"Mosaic Authorization
process\""); header("HTTP/1.0 401
Unauthorized");
//Result if user hits cancel button
login_error(); } else {
//check the login and
password if('=>test on login and password<=') { //User
is logged ... ... } else { //This re-asks three
times the login and password. header( "WWW-Authenticate: Basic
realm=\"Test Authentication System\"");
header("HTTP/1.0 401 Unauthorized");
//Result if user
does not give good login and pass login_error(); } }
|
|
dowlingw at bigfoot dot com
02-Jun-2002 06:29 |
|
Using the same salt for all things is a bad idea.
Use the first two
letters of the username - this also makes moving to other .htaccess based
systems easier :)
|
|
05-Jun-2002 09:08 |
|
A more elegant way to force a new name/password, cf. example 17-2 (if you
don't mind passing the old user in the query string):
<? if
(isset($PHP_AUTH_USER)) { if
(!isset($prev_user)) { header("Location: ); exit; } else { if
($PHP_AUTH_USER == $prev_user) { header('WWW-Authenticate:
Basic realm="Secure"'); header('HTTP/1.0 401
Unauthorized'); exit; } } } else { header('WWW-Authenticate:
Basic realm="Secure"'); header('HTTP/1.0 401
Unauthorized'); exit; } ?>
The final set of headers is
necessary because some browsers seem to unset $PHP_AUTH_USER when the
location header is sent.
|
|
admin at creationfarm dot com
07-Aug-2002 06:24 |
|
I have written a class for HTTP Authentication in PHP. Anyone looking for a
shortcut can get it from:
Feel
free to make suggestions and contributions to the class. It needs some
improvement.
|
|
robdemos at cistron dot nl
09-Aug-2002 04:09 |
|
Hello all,
I've just found a great article about authentification in
php with and without the apache environment, it's as flexible as can be
and it works really great and secure.
See for yourself at
|
|
yaroukh at email dot cz
12-Jan-2003 11:13 |
|
spamsyntax: In Mozilla this doesn't work. Log in, then click
"logout", cancel the pop-up window, go Back - you are logged in
again ... (Mozilla 1.2, Win32)
|
|
yaroukh at email dot cz
12-Jan-2003 11:42 |
|
Here is my solution - works in MSIE and Mozilla.
I use
http-authentication only for the first time user accesses his private
page; after valid username and password are provided, he is recognized
using his sessionID and ip ... the reasons are following: 1) when
users changes his password it is not required instantly (I find this
quite comfortable) 2) auto-login function works fine (unless user click
logout)
And here's how i works ...
The "trick" is
to pass a temporary username+password to the browser. (I call it
"temporary" because no user account matching these parameters
is neccessary.)
The most essential thing is the following link on
user's private page:
=== <? $url = ". $username. // see
note 1 ":". Session_ID(). // see note
2
"@localhost/".PROJECT_NAME."/logout.phtml"; ?> <a
href="<?=$url?>">logout</a> ===
1) we
pass the actual username because MSIE uses this username as a
"default pre-fill" for the login-window and some hash-string
would confuse the users. 2) the temporary password is not too
important, but there are two things we expect from it: a) we
need to know this string in the logout.phtml script b) the string
definetely should not match the user's password (otherwise user
gets logged back instantly); using current Session_ID() we are
pretty sure this won't happen
This link causes that the temporary
login-params are available in the logout.phtml script. Using
"www-authenticate" header in the logout.phtml script we
force the browser to accept our temporary login-params. (I suppose
browser actually repeats the request and the next time it checks the
login-params sent in the URL; but this is only my guess and it is not
important.)
The logout.phtml code: === <? $query =
"UPDATE users SET sessionID = NULL ". "WHERE
sessionID = '".Session_ID()."'";
$mysql->query($query); // because we (me :o) use the sessionID
and the ip for // the identification we need to clean the
sessionID; (I found it // a little bit easier to destroy the
sessionID in the db than // unsetting the cookie and/or
destroying+restarting // the current session)
if($PHP_AUTH_PW != Session_ID()) { // keep asking for the
login-params untill PHP_AUTH_PW returned // by the browser
matches the current Session_ID() (which means // that the
browser accepted the temporary login-params // we sent to it
AND FORGOT THE REAL ONES)
Header("HTTP/1.0 401
Unauthorized"); Header("WWW-Authenticate: Basic
realm=\"".PROJECT_NAME."\"");
} ?> <html> <head> <meta
http-equiv="author" content="yaroukh at email dot
cz">
<title><?=PROJECT_NAME?></title> <link
rel="stylesheet" href="style.css"
type="text/css"> </head> <body>
<a href=">/main.phtml">continue</a>
</body> </html> ===
About the
"continue" link: the link is not too important, but using
it we can get rid off the temporary login-params which wouldn't
look too aesthetically in the address-bar. :o)
|
|
emmanuel dot keller at net2000 dot ch
14-Jan-2003 09:14 |
|
Some servers won't support the HTTP1.0 specification and will give an error
500 (for instance). This happened with a server where I uploaded an
authentication script.
If it happens, you can try the HTTP1.1
header syntax :
header("WWW-Authenticate: Basic
realm=\"My Realm\""); header('status: 401
Unauthorized');
|
|
JKi
14-Feb-2003 10:38 |
|
To clear HTTP authentication cache in Internet Explorer (6 SP1 and later),
use "ClearAuthenticationCache"
command.
document.execCommand("ClearAuthenticationCache");
|
|
25-Apr-2003 12:02 |
|
@emmanuel dot keller at net2000 dot ch: The behaviour you report bases
on the fact that PHP installed as a CGI program must send CGI status
messages instead of HTTP return codes. Therefore, anywhere you normally
send "HTTP/1.0 xyz", you have to send "Status: xyz".
|
|
h1suzuki at hotmail dot com
11-May-2003 07:27 |
|
my solution to use SSL for password encryption, because the password is
sent to web server as plain text. insert the following code snipet into
the top of secure page.
if (!isset($_SERVER['HTTPS'] ||
$_SERVER['HTTPS']!="on") { header("Location:
https://$_SERVER['SERVER_NAME']".
$_SERVER['REQUEST_URI']); exit; } if
(!isset($_SERVER['PHP_AUTH_USER'] || authenticate()) {
header('WWW-Authenticate: Basic realm="secure"');
header('HTTP/1.0 401 Unauthorized'); echo 'Authorization
Required.'; exit; }
first, redirect to the same URI but
SSL-enabled page. then, do authentication.
|
|
add a note |