410 likes | 565 Views
JAAS. JAVA Security. I primi framework JAVA security mirano a lla protezione dell’utente l’utente dall’esecuzione di codice mobile basandosi su: L’origine del codice Chi ha creato il codice JAAS si preoccupa di proteggere il systema dagli utenti basandosi su:
E N D
JAVA Security • I primi framework JAVA security mirano a lla protezione dell’utente l’utente dall’esecuzione di codice mobile basandosi su: • L’origine del codice • Chi ha creato il codice • JAAS si preoccupa di proteggere il systema dagli utenti basandosi su: • L’identità di chi esegue il codice • I permessi concessi a chi esegue il codice
Motivazioni • Meccanismi di autenticazione possono essere implementati in differenti modi: • Usando un database Oracol • Un’autenticazione NT • Il protocollo LDAP (lightweight access directory protocol) • Il punto è come utilizzare qualunque di questi meccanismi senza cambiare il codice dell’applicazione …
JAAS “JAVA Authentication and Authorization Service”. • Tali API sono un’estensione di J2SE (Java 2 Platform, Standard Edition) 1.3. • Fanno parte delle core API in J2SE 1.4 • Sono parte di J2EE (Java 2 Platform, Enterprise Edition) 1.3 specification.
Nasce JAVA Security • Java nasce per essere utilizzato come codice mobile (applets) • Il modello di sicurezza utilizzato inizialmente mirava a considerare: • La provenienza del codice • Il creatore del codice • Tutti i meccanismi (sandbox, firma digitale del codice, files di policy) erano concepiti per proteggere l’utente dal sistema
JAAS • JAAS consente di effettuare sia autenticazione che autorizzazione • JAAS semplifica la gestione della sicurezza inJAVA inserendo un livello di astrazione tra il livello applicativo e i meccanismi di autenticazione ed autorizzazione sottostanti • Come la maggior parte delle security APIs di JAVA, anche JAAS riesce ad essere indipendente dalle implementazioni utilizzando un sistema di moduli SPIs (Serive Provider Interfaces)
Caratteristiche • JAAS mette a disposizione moduli pre-sviluppati • È possibile sviluppare nuovi moduli o importarne degli esterni • È inoltre possibile utilizzare uno stack di moduli: ogni modulo può utilizzare i meccanismi di un modulo sottostante per interagire con diverse infrastrutture. • L’utilizzo di uno stack di autenticazione riprende il Pluggable Authentication Module (PAM) di Unix
Caratteristiche • JAAS utilizza un approccio simile ad un protocollo di commit a due fasi • JAAS eredita dal security packages di J2SE 1.2 i principi per la configurazione come Policy files ed i Permessi • JAAS infine eredita idee da altri affermati framework per la sicurezza, come i certificati X.509
Subject e Principals • JAAS usa il termine subject per riferirsi a qualsiasi servizio o utente • Per identificare i soggetti con cui interagire si basa su di nomi. Tuttavi i soggetti potrebbero avere nomi diversi per utilizzre servizi diversi Le interfacce utilizzate sono: public interface Principal { public String getName(); } public final class Subject { public Set getPrincipals() { } }
Utilizzo • Se la versione di JAVA è anteriore alla J2SEv1.4 occorre procurarsi l’estensione • Occorre salvare il file jaas.jar nel classpath o nella cartella <jre-home>/lib/ext/
Utilizzo Per utilizzare JAAS nelle proprie applicazioni occorre: • Creare un LoginContext • Passare un CallbackHandler al LoginContext, per prelevare o processare i dati utente • Effettuare l’autenticazione chiamando il metodo login() del LoginContext • Effettuare le operazioni privilegiate utilizzando il Subject restituito dal metodo login() (asssumendo che l’autenticazione sia andata a buon fine)
Un esempio LoginContext lc = new LoginContext("MyExample"); try { lc.login(); } catch (LoginException) { // Authentication failed. } // Authentication successful, we can now continue. // We can use the returned Subject if we like. Subject sub = lc.getSubject(); Subject.doAs(sub, new MyPrivilegedAction());
Cosa succede Ecco cosa avviene: • Durante l’inizializzazione dell’oggetto LoginContext viene cercata la entry "MyExample" in un file di configurazione di JAAS (scritto dallo sviluppatore) per capire quale LoginModule caricare • Durante il login, il LoginContext chiama il metodo login() di ogni modulo caricato • Ogni chiamata effettua l’autenticazione o utilizza un CallbackHandler • Il CallbackHandler usa uno o più Callbacks per interagire con gli utenti e prelevare l’input • Viene creata una istanza Subject popolata con dettagli dell’autenticazione quali Principal e Credenziali
Common: Subjects, Principals, and Credentials La classe Subject rappresenta un entità autenticata. La classe contiene tre insieme di informazioni di sicurezza: • Identities: uno o più Principal • Public credentials: es: un nome o una chiave pubblica • Private credentials: password o chiavi private I Principals rappresentano delle identità che un soggetto può assumere (un codicee fiscale, un indirizzo email, una login ID). Implementano l’interfaccia Principal e serializable Una credenziale è un qualsiasi Oggetto (una chiave, un ticket, una password). Tali credenziali vengono usati a livello sistema piuttosto che a quello applicativo.
Authentication: LoginContext È’ la classe direttamente usata dal livello applicativo usato per autenticare i Subjects. All’interno del del LoginContext vengono caricati i moduli pluggable indicati nel file di configurazione I tre metodi usati più comunemente sono: Table 2. LoginContext methods
LoginModule: metodi • Devono essere implementati dal programmatore • Non vengono utilizzati dal livello applicativo, ma dal LoginContext
Authentication: CallbackHandlers and Callbacks • CallbackHandlers and Callbacks fanno si che il LoginModule riesca a prelevare le credenziali dell’utente. • Devono poter essere utilizzati indipendentemente da qual è l’ambito applicativo entro il quale le credenziali sono prelevate (es: e command line o JSP). • JAAS dispone già di 7 built-in Callbacks nel javax.security.auth.callback package: • ChoiceCallback, • ConfirmationCallback, • LocaleCallback, • NameCallback, • PasswordCallback, • TextInputCallback, • TextOutputCallback.
Configuration files Hanno la seguente struttura: Application { ModuleClass Flag ModuleOptions; ModuleClass Flag ModuleOptions; ... }; Application { ModuleClass Flag ModuleOptions; ... }; ... Un esempio: Sample { com.sun.security.auth.module.NTLoginModule Required debug=true;};
Un esempio di login da linea di comando Per utilizzare un database per l’autenticazione: • Creare un database • Creare un file di configurazione che dice al LoginContext come usare il modulo RdbmsLoginModule • Creare un ConsoleCallbackHandler pre prelevare l’input utente • Aggiunfre il codice applicativo per utilizzare il Modulo RdbmsLoginModule, il file di Configurazione, ed il ConsoleCallbackHandler • Nel RdbmsLoginModule, occorre implementare i 5 metodi definiti nella LoginModule interface.
Inizializzazione Il primo di questi metodi è: initialize() : public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options){ this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; url = (String)options.get("url"); driverClass = (String)options.get("driver"); debug ="true“.equalsIgnoreCase((String)options.get("debug"));} The sharedStateMap permette di condividere dati tra diversi LoginModules; un caratteristica non usata qui
Il file di inizializzazione Example {RdbmsLoginModule required driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/jaasdb?user=root" debug="true"; };
L’applicazione ConsoleCallbackHandler cbh = new ConsoleCallbackHandler(); LoginContext lc = new LoginContext("Example", cbh); lc.login();
Our login() method then performs the following steps: • Creates two Callbacks that will receive username/password information from the user. It uses two of the built-in JAAS callbacks from the javax.security.auth.callback package: NameCallback and PasswordCallback. Both of these classes implement the Callback interface, a marker interface with no methods. • Invokes the Callbacks indirectly by passing them to the handle() method of the CallbackHandler parameter specified in the call to initialize(). • Retrieves the username/password from the Callbacks. • Uses the username/password in our own rdbmsValidate() method, which checks them against the database via a JDBC query.
public boolean login() throws LoginException { if (callbackHandler == null) throw new LoginException("no handler"); NameCallback nameCb = new NameCallback("user: "); PasswordCallback passCb = new PasswordCallback("password: ", true); callbacks = new Callback[] { nameCb, passCb }; callbackHandler.handle(callbacks); String username = nameCb.getName(); String password = new String(passCb.getPassword()); success = rdbmsValidate(username, password); return(true);}
public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nameCb = (NameCallback)callbacks[i]; System.out.print(nameCb.getPrompt()); String user=(new BufferedReader(new InputStreamReader(System.in))).readLine(); nameCb.setName(user); } else if (callbacks[i] instanceof PasswordCallback) { PasswordCallback passCb = (PasswordCallback)callbacks[i]; System.out.print(passCb.getPrompt()); String pass=(new BufferedReader(new InputStreamReader(System.in))).readLine(); passCb.setPassword(pass.toCharArray()); } else { throw(new UnsupportedCallbackException(callbacks[i], "Callback class not supported")); } }}
JSP Callback String user = request.getParameter("user");String pass = request.getParameter("pass");PassiveCallbackHandler cbh = new PassiveCallbackHandler(user, pass);LoginContext lc = new LoginContext("Example", cbh);
PassiveCallback public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nameCb = (NameCallback)callbacks[i]; nameCb.setName(user); } else if(callbacks[i] instanceof PasswordCallback) { PasswordCallback passCb = (PasswordCallback)callbacks[i]; passCb.setPassword(pass.toCharArray()); } else { throw(new UnsupportedCallbackException(callbacks[i], "Callback class not supported")); } } }} No richiede interazione con l’utente
Autorizzazione • Una volta che l’autenticazione è stata completata con successo JAAS permette il controllo degli accessi per i principals associati al Subject autenticato • Il controllo dell’accesso JAAS principal-based (basato su chi esegue il codice) completa l’esistente sistema Java 2 codesource-based (basato sulla provenienza del codice e sulla firma)
Autorizzazioni • Occorre definire un insieme di risorse protette • Un insieme di condizioni secondo le quali i Principal menzionati possono accedere alle risorse • JAAS estende la policy di default di Java 2 utilizzando insieme i due criteri (code base and user based)
Esempio • // Java 2 codesource-based policy grant Codebase "http://foo.com", Signedby "foo" { permission java.io.FilePermission "/cdrom/-", "read"; } • // JAAS principal-based policy grant Codebase "http://bar.com, Signedby "bar", Principal bar.Principal "duke" { permission java.io.FilePermission "/cdrom/duke/-", "read"; }
Esempio • Questo esempio consente al codice: • caricato da 'bar.com‘ • firmato da 'bar', • ed eseguito da ‘'duke‘ di leggere solo quei files che si trovano nella cartella '/cdrom/duke' directory. • Per essere eseguito come ‘duke’ il subject autenticato dal LoginContext deve essere associato ad un Principal il cui metodo “getName” ritorna la stringa ‘duke’. • Se il codice caricato da 'bar.com', firmato da 'bar', eseguissse stand-alone (non eseguito come 'duke'), allora non otterrebbe il permesso • Se la policy non specificasse l’informazione Codbase o SygnedBy quel permesso sarebbe concsso a qualunque codice eseguto come ‘duke’
Ruoli e Gruppi • JAAS tratta ruoli e gruppi semplicemente come Principals. • Il controllo dell’accesso può essere applicato a ruoli e gruppi così come ad altri tipi di Principal: // an administrator role can access user password grant Principal foo.Role "administrator" { permission java.io.FilePermission "/passwords/-", "read, write"; // a basketball team (group) can read its directory grant Principal foo.Team "SlamDunk" { permission java.io.FilePermission "/teams/SlamDunk/-", "read"; }
Eseguire un’operazione con particolari Privilegi In JAVA 2 la runtime richiama il Seccurity Manager quando occorre accedere a delle operazioni sensibili Per determinare se il codice ha sufficienti permessi Il SecurityManager delega la responsabilità al “java.security.AccessController” che ottiene un immagine del contesto corrente (AccessControlContext) e si assicura che questi contenga sufficienti privilegi per portare a termine l’operazione.
Eseguire azioni privilegiate con JAAS • JAAS completa questa architettura mettendo a disposizione il metodo: Subject.doAs, per associare dinamicamente un soggetto autenticato al corrente AccessControlContext. • Utilizzando JAAS, il server può essere sicuro di ciò definendo l’operazione qualle java.security.PrivilegedAction, e poi invocando il metodo doAs Fornendo sia il subject autenticato che il PrivilegedAction il metodo doAs associa il subject all’AccessControlContext corrente ed esegue l’azione
Esempio public final class Subject { ... // associate the subject with the current // AccessControlContext and execute the action public static Object doAs(Subject s, java.security.PrivilegedAction action) { } }