CERCA SITEMAP FEED RSS 1280
Ultimo aggiornamento: 30 Agosto 2009

Sicurezza delle web application in JBoss AS 5

Di default le web application non sono sicure, questo significa che se scriviamo una web application e ne effettuiamo il deploy questa risulterà accessibile a chiunque.
I file di configurazione utilizzati in JBoss AS 5 per definire la sicurezza a livello server e a livello applicazione sono:
  • server.xml: configura JBoss Web Server e in particolare può essere usato per definire i connettori.
  • WEB-INF/web.xml e WEB-INF/jboss-web.xml: possono essere usati rispettivamente per definire quali URL proteggere e per puntare al security domain che dovrebbe essere usato per definire i vincoli di sicurezza.
  • login-config.xml: contiene la definizione di security domain che confrontano i dati entranti con i dati memorizzati per autenticare ed autorizzare utenti.

Configurare la sicurezza nel file web.xml

Per specificare autenticazione, autorizzazione e cifratura a livello applicazione viene usato il deployment descriptor standard web.xml:
<web-app>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Risorse</web-resource-name>
      <url-pattern>/*</url-pattern>
      <url-pattern>/shoppingcart/*</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
      <role-name>Ruolo1</role-name>
    </auth-constraint>
    <user-data-constraint>
      <transport-guarantee>
        CONFIDENTIAL
      </transport-guarantee>
    </user-data-constraint>
  </security-constraint>
  <login-config>
    <auth-method>BASIC</auth-method>
  </login-config>
  <security-role>
    <role-name>Ruolo1</role-name>
  </security-role>
</web-app>
Ogni elemento security-constraint definisce i privilegi di accesso a insiemi di risorse specificate dall’elemento web-resource-collection.
Un elemento security-constraint può avere uno o più elementi web-resource-collection oltre ad un elemento auth-constraint e a un elemento user-data-constraint (entrambi opzionali).
Ogni elemento web-resource-collection ha un web-resource-name che definisce il nome della collezione di risorse, un elemento description (opzionale), uno o più elementi url-pattern che definiscono gli url da proteggere (occorre definirne almeno uno altrimenti l’elemento web-resource-collection viene ignorato) e uno o più elementi http-method che definiscono quali metodi http sono protetti.

Il valore di un url-pattern è trattato come segue:
  • una stringa che inizia con / e finisce con /* è usata per path mapping
  • una stringa che inizia con * è usata per extension mapping
  • una stringa contenente solo il carattere / indica il context di default dell’applicazione
  • tutte le altre stringhe sono usate soltanto per match esatti.
L’elemento auth-constraint definisce quali gruppi o principal hanno accesso alle web-resource-collection definite in security-constraint e contiene un elemento description (opzionale) e elementi role-name che definiscono quali ruoli possono accedere alle risorse e sono mappati in principal mediante l’elemento security-role-ref.
L’elemento user-data-constraint definisce come avviene la comunicazione fra client e server e contiene un elemento description (opzionale) e un elemento transport-guarantee che può assumere i valori
  • NONE: l’applicazione non richiede alcuna garanzia di trasporto
  • INTEGRAL: l’applicazione richiede che i dati scambiati fra client e server non posano essere modificati durante il transito
  • CONFIDENTIAL: l’applicazione richiede che i dati siano trasmessi in maniera tale che terze parti non possano accedere al contenuto.
E’ possibile specificare l’autenticazione per l’intera applicazione mediante l’elemento login-config.
Questo elemento contiene al suo interno un elemento auth-method i cuoi valori possibili sono
  • BASIC: usa il modulo di autenticazione del browser
  • FORM: usa un form HTML definito in una pagina
  • CLIENT-CERT: usa i certificati
un elemento realm-name ovvero il nome del reame referenziato per autenticare le credenziali utente e un elemento form-login-config usato per configurare l’auth-metod di tipo FORM e contenente al suo interno un elemento form-login-page contenente l’URI di una risorse web usata per autenticare l’utete e un elemento form-error-page contenente l’URI di una risorsa inviata all’utente quando l’autenticazione fallisce.
L’elemento security-role infine contiene un elemento description (opzionale) ed un elemento role-name contenente il nome del ruolo.
Il file web.xml viene usato per definire quali url devono essere resi sicuri ma non dice nulla su come renderli sicuri.
Questo è compito del security domain che definiamo nel file login-config.xml e punta l’applicazione nel file jboss-web.xml

Configurare la sicurezza nel file jboss-web.xml

Per mappare un’applicazione con un security domain si fa uso del file jboss-web.xml.
Se supponiamo di aver definito nel file login-config.xml un security domain del tipo
<application-policy name="miodominio">
  ...
</application-policy>
Allora il file jboss-web.xml conterrà il mapping:
<jboss-web>
  <security-domain>java:/jaas/miodominio</security-domain>
</jboss-web>
Quando il security framework legge il file login-config.xml crea un security domain collegandolo in JNDI sotto java:/jaas/miodominio.
L’elemento security-domain nel file jboss-web.xml punterà quindi al security domain.

Autenticazione degli utenti

Quando un utente richiede un URL protetto (come definito nell’elemento web-resource-collection nel file web.xml), il server verifica se l’utente è autenticato o meno usando le informazioni memorizzate nella sessione utente.
Se l’utente prova ad accedere ad un URL protetto il container forza l’utente ad effettuare il login mediante un metodo di autenticazione definito per l’applicazione.

I passaggi sono i seguenti:
  • il web container chiede al security framework se la pagina è protetta
  • in caso affermativo il container invia all’utente la pagina di login che l’utente riempie e invia indietro al container
  • il container chiede al security framework se l’utente ha accesso alla pagina
  • il security framework determina se la password fornita dal’utente è la stessa memorizzata nel datastore
  • se ogni cosa corrisponde all’utente viene mostrata la pagina richiesta, altrimenti viene motrata una pagina di errore.
L’autenticazione può avvenire in molti modi, chiedere all’utente di inserire la password di accesso è senza dubbio il più comune.
Java EE definisce due modi principali di autenticazione mediante password: http basic authentication e form-based authentication.
In JBoss è disponibile una terza strategia detta digest authentication.
Oltre a queste strategie esiste un’autenticazione basata sull’utilizzo di certificati detta client-certificate authentication o HTTPS client authentication.
Il deployment descriptor standard WEB-INF/web.xml definisce l’autenticazione usando l’elemento login-config.
<login-config>
  <auth-method>BASIC</auth-method>
</login-config>
L’elemento auth-method definisce la strategia di autenticazione per l’applicazione: i valori consentiti sono BASIC, FORM, DIGEST, CLIENT-CERT.
Una web application può avere un solo blocco login-config definito pertanto si può avere un solo metodo di autenticazione per applicazione.
Le autenticazioni basic e form-based sono quelle più comunemente usate ma esistono due problemi quando le si usa su http: il primo è che l’utente non ha alcuna sicurezza circa l’integrità della sorgente cioè l’identità del server, il secondo è che la password utente potrebbe essere intercettata dal momento che questi metodi di autenticazione non effettuano alcuna operazione di cifratura.
Ciò fa si che queste strategie di autenticazione siano prevalentemente utilizzate sotto HTTPS.

Basic authentication

L’autenticazione http basic fa parte delle specifiche http, quando un utente richiede un URL protetto, il container determina se l’utente è loggato o meno.
Se non lo è chiede all’utente di fornire le credenziali inviando un messaggio http 401 che causa la visualizzazione da parte del browser di un prompt per l’inserimento di username e password.
Quando l’utente inserisce username e password il browser codifica le informazioni usando la codifica base64 e le invia al web container per l’autenticazione attaverso il security framework.
L’autenticazione di tipo BASIC si configura nel file WEB-INF/web.xml usando la dichiarazione login-config
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>webapp</realm-name>
</login-config>
L’elemento auth-method specifica che deve essere usata l’autenticazione basic mentre l’elemento realm-name specifica un testo che verrà inviato al client quando richiede un URL protetto (molti browser visualizzano questo nome nel prompt).

Form-based authentication

La maggior parte dei siti web fa uso un modulo di login integrato con il look & feel del sito internet evitando l’ utilizzo del form di default prodotto dal metodo basic.
Con l’autenticazione di tipo form-based il container determina sempre se l’utente si è già loggato o meno ma in caso negativo evita di visualizzare il prompt di default usando una pagina HTML contenente un form di login.

L’utente quindi riempie il form e lo invia indietro al server:
<form name="loginForm" method="post" action="j_security_check">
  User Name
  <input type="text" name="j_username">
  Password
  <input type="password" name="j_password">
  <input type="submit" value="login">
</form>
Tale pagina può essere fatta in qualsiasi modo purchè il form contenga come action j_security_check, come name dell’input text j_username e come name dell’input password j_password.
L’autenticazione form-based può essere configurata nel file web.xml nel seguente modo
<login-config>
  <auth-method>FORM</auth-method>
  <form-login-config>
    <form-login-page>/admin/login.html</form-login-page>
    <form-error-page>/admin/bad-login.html</form-error-page>
  </form-login-config>
</login-config>
Il valore di auth-method FORM abilita l’autenticazione form-based, l’elemento form-login-page contiene l’url della pagina di login mentre form-error-page la pagina di errore.

Digest authentication

La digest authentication è simile alla basic authentication ma la password non è inviata in chiaro.
Il client usa una la funzione MD5 per calcolare l’hash della password e altri dati e ricavare una stringa nota come digest che viene inviata al server e confrontata con il valore memorizzato nel security datastore.
La digest autenthication usa una tecnica detta nonce o session token per evitare attacchi di tipo replay su http, anche se per avere comunque una protezione affidabile è bene usare HTTPS.
Per configurare la digest autenthication occorre impostare il file WEB-INF/web.xml nel seguente modo:
<login-config>
  <auth-method>DIGEST</auth-method>
  <realm-name>miapp</realm-name>
</login-config>
Il realm-name ha lo stesso scopo visto nella basic authentication.
Dopo aver definito il file web.xml occorre definire il security domain nel file server/xxx/conf/login-config.xml specificando le specifiche di digest.
<application-policy name="jmx-console">
  <authentication>
    <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
      <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
      <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
      <module-option name="hashAlgorithm">MD5</module-option>
      <module-option name="hashEncoding">rfc2617</module-option>
      <module-option name="hashUserPassword">false</module-option>
      <module-option name="hashStorePassword">true</module-option>
      <module-option name="passwordIsA1Hash">true</module-option>
      <module-option name="storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
    </login-module>
  </authentication>
</application-policy>
Quando si memorizza la password nel datastore (file, database, LDAP) occorre essere sicuri di memorizzare la versione MD5.

Autorizzazione degli utenti

Dopo che l’utente si è autenticato, il web container deve verificare se è autorizzato ad accedere alle risorse richieste: questa operazione prende il nome di autorizzazione.
Le opzioni di configurazione dell’autorizzazione per le web application sono specificate nel file WEB-INF/web.xml mediante l’associazione dei nomi dei ruoli ai pattern URL come mostrato nel seguente esempio:
<security-constraint>
  ...
  <auth-constraint>
    <role-name>Ruolo1</role-name>
    <role-name>Ruolo2</role-name>
  </auth-constraint>
</security-constraint>

...

<security-role>
  <role-name>Ruolo1</role-name>
</security-role>
<security-role>
  <role-name>Ruolo2</role-name>
</security-role>

...
Qualsiasi richiesta fatta su un URL protetto definito dentro l’elemento web-resource-collection di un blocco security-contraint richiade che l’utente appartenga ad uno dei ruoli specificati sotto il blocco auth-constraint mediante l’elemento role-name.
Se si vogliono specificare diversi ruoli per difersi URL pattern si possono definire multipli security-constraint.
Se si vuole permettere a qualsiasi utente autenticato di accedere a un dato URL si può specificare il role-name *
Il comportamento esatto è controllato nella definizione di ream nel file server.xml
<Realm className="org.jboss.web.tomcat.security.JBossWebRealm" certificatePrincipal="org.jboss.security.auth.certs.SubjectDNMapping" allRolesMode="authOnly" />
L’attributo allRolesMode determina il comportamento quando una web application definisce un auth-constraint con role-name pari ad * nel suo file web.xml