Una delle situazioni più comuni che ci si trova ad affrontare nella gestione di un sito web è limitare l'accesso ai contenuti di una directory. Nei casi più semplici non è necessario ricorrere ad un sistema di autenticazione gestito da un'applicazione lato server, ma basta sfruttare gli strumenti messi a disposizione dal nostro web server apache, la cosiddetta autenticazione di base HTTP.
L'esempio classico consiste nell'utilizzare un file di configurazione per-directory .htaccess creato nella directory da proteggere e che riporta direttive di questo tipo:
AuthName "Area Riservata" AuthType Basic AuthUserFile /percorso_del_file/.htpasswd require valid-user
Con l'utility da riga di comando htpasswd
è semplice creare ed aggiornare un file di testo, nell'esempio chiamato .htpasswd, contenente, una per riga, le coppie <username>:<password>.
#crea il file e aggiunge l'utente testuser [root]# htpasswd -c /percorso_del_file/.htpasswd testuser #aggiunge l'utente testuser2 [root]# htpasswd /percorso_del_file/.htpasswd testuser2
Per approfondimenti sull'argomento vi rimando all'articolo I file .htaccess in Apache.
Questa soluzione, molto immediata, presenta però alcuni svantaggi. Innanzitutto scarsa scalabilità: quando il numero di utenti diventa consistente la loro gestione risulta macchinosa e le prestazioni di mod_auth (il modulo che gestisce questo tipo di autenticazione) tendono a peggiorare. Inoltre chi gestisce gli utenti deve avere i privilegi per accedere al server ed utilizzare l'utility htpasswd o almeno quelli per copiare il file delle password nella directory di destinazione. Se poi abbiamo già predisposto per altri scopi un database degli utenti, mantenere allineati i dati di entrambi può risultare complicato.
Una possibile soluzione è rappresentata da mod_auth_mysql, tale modulo consente di memorizzare le credenziali d'accesso in un database MySQL, rendendone la gestione molto più flessibile. In questo primo articolo vedremo come implementare il meccanismo di base, mentre un successivo sarà dedicato all'approfondimento e ad alcune configurazioni più avanzate.
Considerazioni preliminari
Di seguito faremo riferimento all'utilizzo di un file .htaccess, spesso unica soluzione per chi dispone di uno spazio in hosting e non ha accesso al/i file di configurazione di Apache. Questo presuppone che l'hoster abbia provveduto ad installare il modulo mod_auth_mysql, abbia abilitato l'utilizzo dei file .htaccess con la direttiva AccessFileName
, abbia utilizzato l'opzione AuthConfig
in AllowOverride
....insomma abbia predisposto il web server per poter consentire l'autenticazione nella directory desiderata tramite un file di configurazione per-directory.
Chi ha libertà di azione sul server dovrebbe preferibilmente impostare le direttive all'interno di un contenitore <Directory> riferito alla directory da proteggere, a meno che non abbia l'esigenza di cambiare la configurazione run-time senza riavviare Apache. Ricordo brevemente che l'abilitazione della configurazione per-directory obbliga il web server a rilevare la presenza di un eventuale file .htaccess ad ogni richiesta, con un certo dispendio in termini di operazioni di I/O su disco. Tanto maggiore quanto più è articolata la struttura delle directory relativa alla nostra document root ed alle pagine del sito.
Detto questo cominciamo con l'installazione del modulo, chi non fosse interessato a questa sezione può passare direttamente ai paragrafi successivi che si riferiscono alla configurazione di MySQL e Apache.
Installazione di mod_auth_mysql
Il modulo, un po' datato a dire il vero, è disponibile su Source Forge e può essere scaricato direttamente da lì.
Risulta tuttavia più semplice un'installazione da pacchetti precompilati. Nel caso del nostro sistema di riferimento, Fedora , possiamo ricorrere a Yum:
[root]# yum install mod_auth_mysql
Il modulo viene installato come DSO (Dynamic Shared Object), e quindi caricato mediante la direttiva:
LoadModule mysql_auth_module modules/mod_auth_mysql.so
L'installazione genera nella directory /etc/httpd/conf.d il file auth_mysql.conf
al cui interno possiamo trovare l'istruzione sopra menzionata. Il file contiene anche, sotto forma di commenti, alcuni utili esempi di configurazione. Ricordo che all'interno del file di configurazione principale /etc/httpd/conf/httpd.conf possiamo trovare l'istruzione:
Include conf.d/*.conf
che provvede ad includere tutti i file di configurazione specifici presenti nella directory /etc/httpd/conf.d, tra cui il nostro auth_mysql.conf.
Per le altre distribuzioni le operazioni saranno molto simili, per l'installazione dovrete naturalmente fare riferimento al packet manager adottato ed ai path usati per i file di configurazione.
Configuriamo MySQL
In questo primo esempio creeremo un database ed una tabella ad hoc per i nostri scopi. In generale ciò non è necessario: potremmo utilizzare un database ed una tabella già esistenti purché nella sua struttura siano previsti un campo per il nome utente ed uno per la password.
Effettuiamo il login alla console di MySQL come root, o, comunque, come utente che abbia privilegi sufficienti ad eseguire i comandi di seguito riportati. Ovviamente, se vi sono più familiari, potete ricorrere a strumenti di amministrazione visuale per eseguire le medesime operazioni.
mysql> create database apache_auth; mysql> use apache_auth; mysql> CREATE TABLE user_info( -> user_name VARCHAR(30) NOT NULL, -> user_password VARCHAR(20) NOT NULL, -> PRIMARY KEY (user_name) -> ) ENGINE=MyISAM; mysql> GRANT SELECT on apache_auth.* -> TO apache_user@localhost -> IDENTIFIED BY 'miosegreto'; mysql> flush privileges;
A questo punto abbiamo creato il database apache_auth
contenente la tabella minimale user_info
ed un utente, apache_user
,che abbia i privilegi di SELECT sulle tabelle del database. Il nome della tabella, user_info
, non è stato scelto a caso: è quello che Apache si aspetta di default. Lo stesso dicasi per i campi user_name
e user_password
. Per questo primo esempio abbiamo scelto la strada più semplice dei valori predefiniti in modo da ridurre il numero di direttive necessarie alla configurazione. Implicitamente abbiamo supposto che database server e web server girino sulla stessa macchina.
Passiamo ora a popolare la tabella utenti:
mysql> INSERT INTO user_info VALUES ('testuser', 'testpass');
Non preoccupatevi, per ora definiamo password in chiaro, successivamente utilizzeremo le più sicure password cifrate. Con il database abbiamo terminato, semplice no? Passiamo ora al web server.
Configuriamo Apache
Supponiamo di gestire il sito www.miosito.it la cui document root sia /var/www/html/miosito e che la directory da proteggere sia /var/www/html/miosito/dirprotetta. In altri termini a chi digiti http://www.miosito.it/dirprotetta deve essere inibito l'accesso a meno che non fornisca le corrette credenziali.
Come più sopra accennato utilizzeremo un file .htaccess che andrà posizionato nella directory da proteggere ed il cui contenuto sarà:
AuthName "Area Riservata" AuthType Basic #direttive specifiche di mod_auth_mysql AuthMYSQLEnable on AuthMySQLDB apache_auth AuthMySQLUser apache_user AuthMySQLPassword miosegreto AuthMySQLPwEncryption none #fine direttive specifiche require valid-user
Vediamo le direttive nel dettaglio:
AuthName
: un nome identificativo dell'area protetta o in generale un testo che comparirà nella finestra di login;AuthType
: il tipo di autenticazione usato, Basic;AuthMYSQLEnable
: attiva o disattiva l'autenticazione mediante MySQL;AuthMySQLDB
: il nome del database usato per l'autenticazione;AuthMySQLUser
: l'utente MySQL che può accedere in selezione alla tabella degli utenti;AuthMySQLPassword
: la password dell'utente sopra definito;AuthMySQLPwEncryption
: il tipo di cifratura usata per le password, con "none" indichiamo che saranno in chiaro.require valid-user
: l'accesso è consentito agli utente che si sono correttamente autenticati.
A questo punto proviamo la configurazione puntando il nostro browser su http://www.miosito.it/dirprotetta. Innanzitutto le risposta di Apache obbligherà il navigatore a mostrarci una finestra di dialogo per il login. In essa inseriremo i valori "testuser" e "testpass" rispettivamente come nome utente e password. Inviando le credenziali corrette dovremmo accedere al contenuto della directory diversamente riceveremo un errore 401 Authorization Required.
Conclusioni
Come si evince da queste pagine è possibile, con una certa facilità, sostituire il file di testo usato da mod_auth con un più efficiente database MySQL, affidando il compito dell'autenticazione a mod_auth_mysql. I due sistemi possono ovviamente convivere sullo stesso server.
A questo punto risulterà possibile gestire più agilmente le utenze con strumenti visuali quali PHPMyAdmin, MySQL Query Browser, HeidiSQL o altri simili. Oppure potremmo scrivere qualche semplice script PHP che permetta anche a persone poco esperte, di gestire il sistema di autenticazione inserendo, modificando o cancellando record dalla tabella user_info.
Per ora ci fermiamo qui, vi do appuntamento al prossimo articolo in cui approfondiremo alcuni aspetti della configurazione in modo da rendere ancora più efficiente ed adattabile il processo di autenticazione.