Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Autenticazione con Apache e MySQL: alcune configurazioni avanzate

Per proteggere le aree riservate del nostro sito possiamo far sì che Apache recuperi i dati di login da un database MySQL. Ecco alcune configurazioni avanzate
Per proteggere le aree riservate del nostro sito possiamo far sì che Apache recuperi i dati di login da un database MySQL. Ecco alcune configurazioni avanzate
Link copiato negli appunti

Nel precedente articolo avevamo realizzato un'area riservata ricorrendo a mod_auth_mysql, facendo cioè interagire Apache con MySQL. La soluzione presentata risultava maggiormente flessibile e scalabile rispetto a quella classica offerta da mod_auth, che si appoggia ad un file di testo per gestire utenti e password.

Ci eravamo proposti l'obbiettivo di proteggere una directory del nostro sito mediante un file .htaccess, memorizzando le credenziali d'accesso in una tabella del database MySQL. Dopo le operazioni preliminari d'installazione e configurazione eravamo giunti ad un primo semplice esempio:

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

La tabella di MySQL creata aveva la seguente struttura:

mysql> describe user_info;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| user_name     | varchar(30) | NO   | PRI | NULL    |       | 
| user_password | varchar(20) | NO   |     | NULL    |       | 
+---------------+-------------+------+-----+---------+-------+

Di seguito vedremo come sia possibile agire sulle direttive del file di configurazione per-directory, per ottenere soluzioni più avanzate.

La cifratura delle password

Il primo elemento da migliorare è, senza ombra di dubbio, il sistema di memorizzazione delle password. Ci eravamo accontentati di salvare questa informazione in chiaro: soluzione sicuramente sconsigliabile dal punto di vista della sicurezza. Agiremo ora sulla direttiva AuthMySQLPwEncryption che prevede le seguenti opzioni:

  • none: password in chiaro, la soluzione momentaneamente adottata nell'esempio;
  • crypt: la tipica cifratura UNIX ottenibile con la funzione crypt();
  • scrambled: la cifratura propria di MySQL;
  • md5: hash MD5;
  • aes: la cifratura con AES Advanced Encryption Standard, il formato del campo deve essere un TINYBLOB;
  • sha1: la cifratura con Secure Hash Algorihm.

Non abbiamo che l'imbarazzo della scelta, modifichiamo la direttiva dell'esempio così:

AuthMySQLPwEncryption scrambled  

In questo caso abbiamo scelto la cifratura nativa di MySQL ottenibile mediante la funzione PASSWORD(). La query d'inserimento per il nostro utente di prova sarà:

mysql> INSERT INTO user_info VALUES ('testuser', PASSWORD('testpass')); 

Altrettanto semplice sarebbe stata l'adozione del parametro crypt, cui corrisponde la funzione ENCRYPT(), che utilizza la system call Unix crypt(). Vi rimando alla documentazione ufficiale per ulteriori informazioni relative alle funzioni di cifratura di MySQL.

Una puntualizzazione importante: l'adozione della cifratura consente la protezione dal punto di vista dell'accesso al database. Ovvero una persona non autorizzata, che dovesse visualizzare il contenuto della tabella utenti, non potrebbe interpretare le password. Al momento dell'immissione delle credenziali la connessione tra client e server rimane però in chiaro, a meno che non si ricorra ad una connessione SSL/TLS.

Aggiungiamo i gruppi

Spesso le autorizzazioni sulle risorse vengono gestite più agilmente mediante la creazione di gruppi. Questo permette di non enumerare nella direttiva require tutti i nomi utente necessari, ma di limitarsi al/ai gruppi di appartenenza:

#elencazione degli utenti
require user testuser ermanno mario ....

#riferimento semplicemente al gruppo
require group amministratori

Modifichiamo la nostra tabella in modo da prevedere un campo per i gruppi ed inseriamo un utente amministratore, chiamato testadmin:

mysql> ALTER TABLE user_info ADD user_group varchar(20) NOT NULL DEFAULT '';

mysql> UPDATE user_info SET user_group = 'utenti' WHERE user_name='testuser';
                                           
mysql> INSERT INTO user_info VALUES ('testadmin', PASSWORD('admpass'), 'amministratori');

Modifichiamo il file .htaccess dell'esempio:

AuthName "Area Riservata"
AuthType Basic

AuthMYSQLEnable on                                              
AuthMySQLDB apache_auth
AuthMySQLUser apache_user
AuthMySQLPassword miosegreto
AuthMySQLPwEncryption scrambled
AuthMySQLGroupField user_group
                                                                                                                                          
require group amministratori            

AuthMySQLGroupField ci permette di specificare il nome del campo usato per memorizzare il gruppo d'appartenenza, in modo che Apache possa correttamente effettuare la query. Con require group amministratori imponiamo che solo gli utenti di tale gruppo possano avere accesso. Le credenziali di testuser verranno rifiutate, contrariamente a quelle di testadmin.

Approfondiamo ancora l'argomento: spesso risulta necessario assegnare ad un utente diversi gruppi. In questo caso per realizzare il legame 1 → N dobbiamo ricorrere ad una tabella esterna. Creiamola, aggiorniamo i dati ed eliminiamo il campo user_group da user_info:

mysql> CREATE TABLE groups(                
    -> user_name VARCHAR(30) NOT NULL,                                                                         
    -> user_group VARCHAR(20) NOT NULL,                                                
    -> PRIMARY KEY (user_name, user_group)
    -> ); 
    
mysql> INSERT INTO groups VALUES ('testuser', 'utenti');
mysql> INSERT INTO groups VALUES ('testadmin', 'amministratori');
mysql> INSERT INTO groups VALUES ('testadmin', 'utenti');

mysql> ALTER TABLE user_info DROP COLUMN user_group; 

Ora dobbiamo aggiungere al file .htaccess la seguente direttiva:

AuthMySQLGroupTable groups 

per indicare ad Apache la tabella usata per gestire i gruppi. A questo punto mediante la direttiva require group utenti possiamo creare una directory accessibile contemporaneamente a testuser e testadmin in quanto membri del medesimo gruppo utenti. Possiamo crearne una seconda, riservata a testadmin, con require group amministratori.

Utilizziamo la nostra tabella utenti

Spesso accade che esista già una tabella utenti, precedentemente creata per altre finalità. Sarebbe comodo utilizzarla senza dover costruire un archivio parallelo. Per fortuna mod_auth_mysql risulta sufficientemente adattabile da permetterci tale operazione. Consideriamo di disporre nel database clients di una tabella chiamata users, contenente una serie di campi ben superiore rispetto alla user_info degli esempi iniziali.

Potrebbe essere qualcosa di simile:

mysql> describe users;
+-------------+-------------------+------+-----+---------+----------------+
| Field       | Type              | Null | Key | Default | Extra          |
+-------------+-------------------+------+-----+---------+----------------+
| UserId      | int(8) unsigned   | NO   | PRI | NULL    | auto_increment | 
| UserLogin   | varchar(25)       | NO   |     | NULL    |                | 
| UserPass    | varchar(32)       | NO   |     | NULL    |                | 
| UserActive  | tinyint(1)        | NO   |     | 1       |                |
...............

I puntini stanno ad indicare che l'elenco dei campi descrittivi potrebbe tranquillamente continuare.
Il problema a questo punto risulta istruire Apache perché possa recuperare i dati corretti:

AuthMYSQLEnable on                                              
AuthMySQLDB clients
AuthMySQLUser cliuser
AuthMySQLPassword miosegreto
AuthMySQLPwEncryption md5                     
AuthMySQLUserTable users 
AuthMySQLNameField UserLogin 
AuthMySQLPasswordField UserPass

Niente di più semplice: con AuthMySQLDB specifichiamo il database, con AuthMySQLUserTable il nome della tabella su cui effettuare la select, con AuthMySQLNameField e AuthMySQLPasswordField il nome dei campi utilizzati per memorizzare username e password. Naturalmente dovremo specificare anche i dati relativi alla connessione al database e l'algoritmo adottato per memorizzare le password.

Possiamo andare oltre: se il campo UserActive viene utilizzato per discriminare utenti attivi da utenti disattivati dobbiamo inserire una condizione nella select effettuata da Apache. Qualcosa di simile a AND UserActive = '1'. La seguente direttiva fa al caso nostro:

AuthMySQLUserCondition UserActive=1

Se a questo punto consideriamo che AuthMySQLUserTable consente di specificare più di una tabella, provate ad immaginare come si possa sfruttare AuthMySQLUserCondition per effettuare delle join. Con un po' di applicazione risulterà possibile far eseguire ad Apache delle query non banali.

Il medesimo discorso vale per la direttiva AuthMySQLGroupTable con la corrispondente AuthMySQLGroupCondition.

Conclusioni

In queste pagine abbiamo affrontato le principali direttive messe a disposizione da mod_auth_mysql salvo forse AuthMySQLHost, che permette la connessione ad un server diverso da localhost. E AuthMySQLPort per specificare una porta diversa dalla 3306 di default. Le caratteristiche descritte contribuiscono a renderlo uno strumento alternativo a mod_auth. Senza per questo rinunciare alla possibilità di utilizzarli in parallelo. Per ulteriori approfondimenti e dettagli potete fare riferimento alla documentazione ufficiale.

Ti consigliamo anche