Autenticazione in una web application con Glassfish in 5 semplici passi

Lavorando su Tomcat, avevo sempre gestito l’autenticazione (per l’accesso a contenuti protetti) nelle web application  in modo semplice e veloce tramite il meccanismo dei Realm (http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html). Passando a Glassfish e cercando qualcosa di simile, non ho trovato una documentazione chiara che spiegasse passo passo come riuscire a realizzare il mio obiettivo. Pescando qua e là mi sono comunque accorta che il meccanismo è altrettanto semplice che su Tomcat, e non molto dissimile. Il procedimento illustrato è lo stesso per Glassfish 3.0.1 e Glassfish 3.1.1. Per la memorizzazione delle credenziali degli utenti utilizzerò un database MySql.

Autenticazione con Glassfish

Vediamo come fare in cinque semplici passi.

1) Creare le tabelle nel database

Dobbiamo creare due tabelle nel database (come facevamo anche con Tomcat), una per gli utenti ed una per i ruoli. Creiamo la tabella utenti:

CREATE TABLE `utenti` (
  `username` varchar(200) NOT NULL DEFAULT '',
  `nome` varchar(200) DEFAULT NULL,
  `cognome` varchar(200) DEFAULT NULL,
  `email` varchar(200) NOT NULL DEFAULT '',
  `password` varchar(200) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Creiamo la tabella ruoli:

CREATE TABLE `ruoli` (
  `username` varchar(200) NOT NULL DEFAULT '',
  `ruolo` varchar(200) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

2) Creare una risorsa JDBC

Dobbiamo creare la risorsa JDBC necessaria per collegarsi al database dove memorizziamo gli username e le password degli utenti autenticati. In questo post spiego come impostare su Glassfish una risorsa JDBC per il collegamento con un database.

3) Creare il Security Realm

Andiamo quindi a creare il Security Realm, che utilizzerà la risorsa JDBC appena creata per recuperare le credenziali degli utenti. Per fare questo apriamo l’interfaccia web di gestione di Glassfish (di default raggiungibile alla porta 4848). Nel menù di sinistra cerchiamo Security, apriamo il collegamento e quindi clicchiamo su Realm.

Selezionare Realm dal gruppo Security

Clicchiamo su New e riempiamo il form inserendo un nome univoco per il realm e scegliendo com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm dal menù a tendina. Dopo la scelta appariranno sotto altri campi: andiamo a riempirli:

  • JAAS Context: qui dobbiamo inserire esattamente la stringa “jdbcRealm”. Questo punto è IMPORTANTE, anche perché non è indicato bene da nessuna parte…
  • JNDI: l’identificativo della risorsa JDBC per il collegamento ad database. ES. jdbc/test
  • User Table: la tabella nel database che contiene gli utenti. Es. utenti
  • User Name Column: la colonna che contiene lo username nella tabella degli utenti. Es. username
  • Password Column: la colonna che contiene la password nella tabella degli utenti. Es. password
  • Group Table: la tabella che contiene i ruoli degli utenti. Es. ruoli
  • Group Name Column: la colonna che contiene il ruolo dell’utente nella tabella dei ruoli (la colonna che contiene lo username deve avere lo stesso nome che ha nella tabella degli utenti). Es. ruolo
  • Digest Algorithm: l’algoritmo usato per cifrare la password. ATTENZIONE, c’è una leggera differenza tra le varie versioni di Glassfish, quello che cambia è il valore di default. Inseriamo ad esempio MD5.

4) Modificare il file web.xml

Questo passo è esattamente lo stesso che facevamo per le web application su Tomcat. Dobbiamo configurare nel file web.xml il security contraint, la modalità di login, ed i ruoli utilizzati. Dobbiamo solo fare attenzione ad inserire come realm name l’identificativo che abbiamo indicato nella creazione del realm su Glassfish.

<security-constraint>
<display-name>Area Protetta</display-name>
        <web-resource-collection>
            <web-resource-name>Area Protetta</web-resource-name>
            <description/>
            <url-pattern>/faces/protected/*</url-pattern>
            <url-pattern>/protected/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>registered</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>testRealm</realm-name>
        <form-login-config>
            <form-login-page>/login.jsp</form-login-page>
            <form-error-page>/login_error.jsp</form-error-page>
        </form-login-config>
    </login-config>
    <security-role>
        <description/>
        <role-name>registered</role-name>
    </security-role>

5) Modifichiamo il file sun-web.xml (o glassfish-web.xml)

L’ultimo passo consiste nel creare un mapping tra i ruoli della web application e i gruppi di Glassfish. Qui troviamo una piccola differenza tra le diverse versioni di Glassfish: nell’ultima versione abbiamo il file glassfish-web.xml, mentre nelle versioni precedenti troviamo il file sun-web.xml; il contenuto da aggiungere è comunque lo stesso: per ogni ruolo utilizzato aggiungiamo una definizione di security role mapping:

  <security-role-mapping>
    <role-name>registered</role-name>
    <group-name>registered</group-name>
  </security-role-mapping>

Ecco fatto! Adesso quando un utente richiede le pagine inserite nell’area protetta sarà reindirizzato sulla pagina di login e potrà visualizzare i contenuti protetti solo se possiede un ruolo autorizzato.

Nota: lavorando su NetBeans possiamo editare sia il file web.xml che il file sun-web.xml (o glassfish-web.xml) tramite interfaccia visuale e definire quindi in questo modo sia l’area protetta che il mapping tra ruoli e gruppi.

Creazione dell'area protetta su Netbeans

Autore: Evelina Agostini

Evelina Agostini si è laureata con lode in Ingegneria Informatica presso l'Università degli Studi di Firenze e può vantare un'esperienza decennale nello sviluppo di soluzioni web. Dotata di competenze trasversali a tutto lo stack, conosce in maniera approfondita la piattaforma Java EE ed in generale le tecnologie server side sia Java che PHP, ed è in grado di progettare e realizzare database scalabili utilizzando sia MySQL che Oracle. Evelina possiede inoltre competenze su Javascript e jQuery e skill internazionalmente riconosciuti per quanto riguarda il framework AngularJS ed in generale le soluzioni Javascript MVC. Evelina, grazie alle sue doti creative, si occupa anche del design di alcune delle interfacce dei sistemi sviluppati da ELbuild.

5 pensieri riguardo “Autenticazione in una web application con Glassfish in 5 semplici passi”

  1. Proprio in questi giorni sto affrontando il tema dell’autenticazione con Glassfish per una web application (basata su Struts2 e JPA EcplipseLink 2.0) che sfrutterà un database derby (o forse mysql, ma poco importa). Fino ad ora conoscevo soltanto la metodologia offerta da Spring Security (che non vorrei usare).
    Questo articolo è molto interessante, ma sarebbe molto utile integrarlo con gli articoli

    security-webapps.html
    e
    netbeanse security e-commerce

    In conclusione, sarebbe interessante avere un articolo omogeneo che descrive l’autenticazione di una Web Application appoggiandosi al database e non ad un file di configurazione. Ovvero prendere spunto da questo articolo ed integrarlo con le specifiche descritte nei due link sopra.

    Esiste qualcosa del genere?

    1. Salve Mau. Ti ringrazio per l’interessamento. In effetti l’approccio descritto in netbeanse security e-commerce è molto simile a quello che ho seguito, eccetto il fatto che non utilizza un database per mantenere i dati sugli utenti, cosa che molto spesso è necessaria in un’applicazione reale. Ovviamente io ho lasciato alcune parti sottointese, in quanto mi interessava evidenziare le peculiarità dell’uso di Glassfish rispetto ad altri Application Server (in particolare rispetto a Tomcat) e quindi ho dato per chiare le parti in comune. Certo potrebbe essere interessante creare una guida più completa….grazie per il suggerimento! 😉

      1. Quello che ancora non ho capito e non ho trovato in rete, è come effettuare il “mapping” dell’entità utente con le specifiche di autenticazione JDBCRealm di Glassfish.
        Spring Security, ad esempio, usa qualcosa del genere
        @Entity
        public class MyUser implements org.springframework.security.core.userdetails.UserDetails e l’ovverride del metodo getAuthority per il ruolo (gruppo utenti) e di tutti quelli richiesti da Spring Security.

        Per Glassfish occorrerà sicuramente fare qualcosa di simile, sfruttando forse le classi di com.sun.enterprise.security… ?

        Mi sto documentando; spero di arrivare presto a qualcosa di concreto e pubblicabile … 🙂

        1. Capisco cosa intendi, è interessante; io ho sempre gestito le due cose in modo indipendente. Non sono sicura che si possa fare semplicemente tramite l’application server; Spring è comunque un framework abbastanza potente che ovviamente ti fornisce una serie di utilità in questo senso. Ma vale la pena di investigare il discorso…grazie dello spunto! 🙂

          1. Finalmente ci sono riuscito 🙂
            Non esiste alcun ingrediente speciale per ottenere la cosa. E’ sufficiente configurare jdbcRealm utilizzando i nomi tabella e i nomi campo come sono stati definiti nelle Entity.
            Ci sono ancora dei punti oscuri da risolvere poiché la versione 3.1.2 di Glassfish ha introdotto alcune differenze nella gestione degli algoritmi di cifratura e digest. Inoltre sembra che ogni algoritmo abbia un JAAS Context diverso associato e questo non mi pare sia scritto da nessuna parte: infatti il mio test funziona senza cifratura….

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *