Authentication
After setting up your DAV server, you will probably want to add some security. The standard way to do this, is to add HTTP Basic or HTTP Digest authentication support.
sabre/dav comes with a plugin that handles authentication for you. It is recommended to use this plugin, and it is required to use for both cal- and carddav.
The plugin can work with different backends. SabreDAV ships with a number of backends, but it's also easy to create your own.
Backends
SabreDAV comes with the following backends:
Class | Type | Description |
---|---|---|
Sabre\DAV\Auth\Backend\Apache |
N/A | Lets the webserver handle authentication |
Sabre\DAV\Auth\Backend\BasicCallBack |
Basic | Extremely easy way to create authentication from a custom source |
Sabre\DAV\Auth\Backend\File |
Digest | Use a htdigest file for its backend |
Sabre\DAV\Auth\Backend\PDO |
Digest | Use a database, such as sqlite or mysql |
Sabre\DAV\Auth\Backend\IMAP |
Basic | Use an imap server |
Using the PDO backend
The PDO backend can either use MySQL or SQLite databases. An example for the
table creation can be found in the source in the examples/sql
directory.
Assuming you already have a server up and running, add the plugin using the following code:
use Sabre\DAV\Auth;
$pdo = new \PDO('sqlite:data/db.sqlite');
// or alternatively:
// $pdo = new \PDO('mysql:dbname=sabredav','username','password');
// Throwing exceptions when PDO comes across an error:
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
// Creating the backend.
$authBackend = new Auth\Backend\PDO($pdo);
// We're assuming that the realm name is called 'SabreDAV'.
$authBackend->setRealm('SabreDAV');
// Creating the plugin.
$authPlugin = new Auth\Plugin($authBackend);
// Adding the plugin to the server.
$server->addPlugin($authPlugin);
The SQL table
The example scripts for the SQL tables automatically creates a user with the
username admin
and password admin
. Change this!
You might be confused by the digesta1
field. This field actually contains
the hashed password. The password is stored in the following format:
md5('username:realm:password');
The username and password speak for themselves, but it's important to keep
the realm
in mind. This must be the very same realm you specified earlier
when creating the Sabre\DAV\Auth\Plugin
.
If you choose to change the realm in the plugin, existing passwords will be invalidated, because the hash changed for all of them.
Using the File backend
The Sabre\DAV\Auth\Backend\File
backend uses a simple file to store
usernames and passwords. The format of the file is identical to Apache's
htdigest
file.
If you have Apache installed, there's a good chance you have a utility
to create and modify these files. You can verify this by typing htdigest
on the command line.
If you don't have htdigest
installed, the format is rather simple.
Every user is on a single line (split by \n
). Every line looks like:
username:realm:digesta1
The username speaks for itself, the realm must be the exact same as the second
argument of the Sabre\DAV\Auth\Plugin
constructor, and the digesta1
is,
just like with the PDO plugin the following hash:
md5('username:realm:password');
So, given a username of 'foo'
, a password of 'bar'
, and a realm of
'SabreDAV'
, the resulting hash should be:
$ php -r "echo md5('foo:SabreDAV:bar');"
5790c3784a79a018d1186528df520e11
Then our htdigest
file looks like:
foo:SabreDAV:5790c3784a79a018d1186528df520e11
To use this file:
use Sabre\DAV\Auth;
$authBackend = new Auth\Backend\File('/path/to/htdigest');
$authBackend->setRealm('SabreDAV');
$authPlugin = new Auth\Plugin($authBackend);
// Adding the plugin to the server.
$server->addPlugin($authPlugin);
Using the IMAP backend
You can use the IMAP backend to authenticate against an IMAP server like dovecot, cyrus or any other.
Assuming you already have a server up and running, add the plugin using the following code:
use Sabre\DAV\Auth;
// Set IMAP flags according to your needs.
// The connection will be opened read-only.
// https://php.net/manual/de/function.imap-open.php
$mailbox = '{localhost:993/notls}';
// Creating the backend.
$authBackend = new Auth\Backend\IMAP($mailbox);
// We're assuming that the realm name is called 'SabreDAV'.
$authBackend->setRealm('SabreDAV');
// Creating the plugin.
$authPlugin = new Auth\Plugin($authBackend);
// Adding the plugin to the server.
$server->addPlugin($authPlugin);
Creating your own authentication backend
If you're going to add Digest authentication, use
Sabre\DAV\Auth\Backend\AbstractDigest
as your parent class, and the
Sabre\DAV\Auth\Backend\File
and Sabre\DAV\Auth\Backend\PDO
classes as examples.
If you're going to implement HTTP Basic, you must use
Sabre\DAV\Auth\Backend\AbstractBasic
as your parent class and implement the
validateUserPass
method.
Webserver configuration
Some webservers may require special configuration for authentication to work. Take a look at Webservers for more information.
Problems with safe mode
If 'safe mode' is enabled, PHP will automatically append a process ID to authentication realms. This is problematic for Digest authentication, as it used the realm to determine the hash.
The solution to this is to either turn off Safe Mode, or using Basic authentication instead of Digest.
See the PHP manual for more information.
Encoding issues
Avoid non-ASCII characters for passwords. We've noticed that different clients may use different encodings for passwords (windows may use CP-1252 and others UTF-8), so each results in a different password string.
In the case of Basic authentication we could normalize this (but we don't), but in the case of Digest, different encodings result in completely different hashes, and this is only fixable by pre-generating hashes for every potential encoding.
SabreDAV does not do any of this, so stick to ASCII passwords.
Letting the webserver handle authentication
Authentication can be directly handled by webservers as well. This approach can be useful if you want to use advanced authentication methods provided by Apache modules (for instance LDAP, Kerberos or SASL).
The backend to support this is called Sabre\DAV\Auth\Backend\Apache
, to use
it add the plugin as follows:
use Sabre\DAV\Auth;
// Creating the backend.
$authBackend = new Auth\Backend\Apache();
// Creating the plugin.
$authPlugin = new Auth\Plugin($authBackend);
// Adding the plugin to the server.
$server->addPlugin($authPlugin);