Authentication and authorization in PHP
| Introduction | |
| Authentication | |
| Authorization | |
| Predefined variables | |
| Basic HTTP authentication | |
| Digest authentication overview | |
| Form based authentication |
Predefined PHP variables
- PHP_AUTH_USER
- PHP_AUTH_PW
- AUTH_TYPE
Basic HTTP Authentication
To check a user in a popup window this code is enough:
<?php
// www.aredel.com lesson
$username = 'eth1.ru';
$password = 'heihei.ru';
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Andrei"');
}
Still, it is worth adding some functionality:
<?php
$username = 'eth1.ru';
$password = 'heihei.ru';
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Andrei"');
header('HTTP/1.0 401 Unauthorized');
echo 'Enter login and password to access the page';
exit;
}
else {
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>You entered password {$_SERVER['PHP_AUTH_PW']} .</p>";
}
if ($_SERVER['PHP_AUTH_USER'] !== $username ||
$_SERVER['PHP_AUTH_PW'] !== $password
) {
header('HTTP/1.0 401 Unauthorized');
echo 'Username or password are incorrect
';
exit;
}
This code works rather poorly - entering a wrong password gives no
second attempt. You have to close the tab, go to browser history and delete
the data there.
In
Firefox
In Firefox, it is Library → History → Clear Recent History → Active Logins
In Chrome it is
Passwords and other sing-in data (in Clear browsing data → Advanced)
In Safari it is Clear History
If the password changed, the user with the old password is not kicked out, etc.
Compatibility note
Please be careful when encoding HTTP header lines.
To guarantee maximum compatibility with all clients, the keyword "Basic" must be written with a capital "B", the realm string must be enclosed in double (not single) quotes, and exactly one space must precede the 401 code in the HTTP/1.0 401 header line. Authentication parameters must be separated by commas, as shown in the digest example above.
Clear global variables
Clear variable values $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'] can be done with the function unset()
unset($_SERVER['PHP_AUTH_USER']); unset($_SERVER['PHP_AUTH_PW']);
HTTP Digest Authentication
Digest access authentication
— is one of the generally accepted methods used by a web server to handle web browser user credentials.
A similar method is used in the VoIP SIP protocol for the server to authenticate client requests, i.e. the endpoint.
This method sends over the network a hash of the login, password, server address and random data, providing more protection than basic authentication, where data is sent in the open.
Technically, digest authentication applies the MD5 cryptographic hash function to the user secret using random values to complicate cryptanalysis and prevent replay attacks. Works at the HTTP protocol level.
This is a more advanced variant of HTTP authentication.
RFC
The following options can be used (
full list in the RFC
)
domain
- domain
Optional space-separated URI list protected by this authentication request.
algorithm
Specifies the algorithm used to create the digest.
opaque
base64 or HEX string generated by the server. The client must return opaque unchanged.
nonce
-
Unique HEX or base64 number the server generates with every 401 request.
Helps the server fight
replay attacks
nonce must be in single quotes (not double)
nonce-count - HEX number with the count of requests the client sent with nonce in the request.
stale
From English stale.
Flag showing that the previous client request was rejected because
the nonce value was stale.
The server must set the stale flag to TRUE (case-insensitive) if the password and username are correct
and only the nonce is stale.
In this case the client may try sending another encrypted request without asking the user
for a password.
If the server refused the connection and stale is FALSE, any value but TRUE, or
missing at all, the client must ask for login and password again.
qop
-
Quality of Protection
Option for HTTP Digest Authentication. Takes "auth" or "auth-int". Affects
how the hash is created.
With "auth" only the requested URI is used. With "auth-int"
the request body is used as well.
rfc2617
cnonce - Unique id generated by the client. This number helps client and server confirm they share a known secret. Required when the server sends qop. Must not be sent if the server did not use the qop directive.
Digest authentication overview
-
Client sends GET to the server.
-
Server replies with HTTP 401 Unauthorized and an option set (digest).
WWW-Authenticate: Digest realm="AndreiR",
qop="auth,auth-int",
nonce="abcdefg…",
opaque="abcd…",
-
User enters credentials
-
Authorization header is generated:
HA1 = MD5 hash of username, password and realm string.
HA2 = MD5 hash of the auth method and requested URI
Response = MD5 hash of HA1, HA2, nonce, nonce-count, cnonce and qop
Client sends a new request based on the generated data
GET /
Authorization: Digest username="andrei", realm="AndreiR", uri="/"
qop=auth, nc=00000001,response="12345abc…"
nonce="abcdefg…",
opaque="abcd…",
- Server checks the incoming data. If all is well returns HTTP 200 OK, otherwise HTTP 403 Forbidden
Some options are optional, so no specific security level can be guaranteed.
HTTP Digest authentication is vulnerable to
man-in-the-middle (MITM) attacks
since the server cannot verify client identity.
Cannot use more complex password hashing algorithms such as
bcrypt
| PHP session locking | |
| Installing PHP frameworks | |
| Installing Yii | |
| Installing Symfony | |
| Installing Laravel | |
| XDebug - debugging and profiling php code |
Article author: Andrei Olegovich