2010-09-30 10 views
9

Sto sviluppando un'applicazione Java EE 6 utilizzando Glassfish 3.1, B06. Per proteggere la mia app, sto usando un JDBCRealm e la sicurezza programmatica. Funziona bene per controllare nome utente e password. Ma quando si tratta di dichiarare ruoli di sicurezza, ho un problema:Aggiungere ruoli di sicurezza Java EE in modo dinamico senza utilizzare il descrittore di distribuzione

Per utilizzare i ruoli di sicurezza in Java EE 6, devo dichiarare quei ruoli sia nel descrittore di distribuzione EJB che nel descrittore di distribuzione specifico di Glassfish per collegarli ruoli (come spiegato nello Java EE 6-tutorial) Solo io posso utilizzare il metodo isCallerInRole (String roleRef) all'interno di un EJB per verificare le autorizzazioni.

Non è consigliabile per la mia applicazione, poiché desidero che sia possibile aggiungere ruoli di sicurezza sia dinamicamente che a livello di codice, senza dover scrivere file XML (e, ad esempio, consentire di definire i nomi dei ruoli in un database).

Ho appena debug attraverso il codice GF3-source e ha visto la realizzazione di isCallerInRole in com.sun.ejb.containers.EjbContextImpl. C'è il contenitore ottiene i ruoli fuori del descrittore di EJB:

public boolean isCallerInRole(String roleRef) { 
    (...) 
    EjbDescriptor ejbd = container.getEjbDescriptor(); 
    RoleReference rr = ejbd.getRoleReferenceByName(roleRef); 
    (...) 
} 

mi sono guardato intorno e ho scoperto che se potessi in qualche modo ottenere il descrittore di EJB all'interno della mia applicazione, ho potuto aggiungere un ruolo come questo:

EjbDescriptor ejbd = //??? Can i use that descriptor inside my app, or is that "forbidden"? 
RoleReference rr = new RoleReference("admin", "Admins are allowed to do everything"); 
ejbd.addRoleReference(rr); 

Qualcuno ha fatto qualcosa del genere, o ci ha pensato? È possibile utilizzare il descrittore di distribuzione Ejb all'interno della mia applicazione? O ci sono approcci migliori?

P.S. o dovrei usare MBeans per aggiungere ruoli? Trovato un post abbastanza correlato here.

+1

Per inciso, vorrei incoraggiarvi a passare a una versione più recente di GlassFish Server 3.1. Il team ha recentemente rilasciato la build 22. – vkraemer

+0

Grazie. Sfortunatamente, abbiamo alcune librerie che si rompono a versioni di Glassfish più alte, quindi dobbiamo restare con 06 fino a quando alcuni bug in queste librerie sono corretti – ifischer

risposta

3

Il Javadoc fa parlare di questa esigenza in modo esplicito:

/** 
    * Tests if the caller has a given role. 
    * 
    * @param roleName - The name of the security role. The role must be one of the security roles that 
    * is defined in the deployment descriptor. 
    * @return True if the caller has the specified role. 
    */ 
    public boolean isCallerInRole(String roleName); 

Tuttavia, ho trovato che almeno con JBoss AS non è richiesto a tutti a dichiarare quei ruoli in anticipo. Nel nostro caso, i ruoli principali vengono creati dinamicamente nel sistema e assegnati quando avviene l'autenticazione. È quindi impossibile dichiararli in anticipo.

Tuttavia, il metodo isCallerInRole funziona perfettamente.

Mi rendo conto che il passaggio a JBoss AS non è una soluzione, ma forse questa informazione è comunque preziosa per qualcuno.

3

mi si avvicinò con la seguente soluzione per aggiungere i ruoli di programmazione dopo il login, che funziona, almeno su GlassFish 3.1.2 costruire 23.

import com.sun.enterprise.security.SecurityContext; 
import com.sun.enterprise.security.web.integration.PrincipalGroupFactory; 
import java.security.Principal; 
import java.util.Set; 
import javax.security.auth.Subject; 
import org.glassfish.security.common.Group; 

public class GlassFishUtils { 
    public static void addGroupToCurrentUser(String groupName, String realmName) { 
     Subject subject = SecurityContext.getCurrent().getSubject(); 
     Set<Principal> principals = subject.getPrincipals(); 
     Group group = PrincipalGroupFactory.getGroupInstance(groupName, realmName); 
     if (!principals.contains(group)) 
      principals.add(group); 
    } 
} 

Sarà necessario aggiungere security.jar e common-util.jar dal GlassFish al progetto librerie.

E non dimenticare di creare una sezione <security-role> nel tuo web.xml per i ruoli che desideri aggiungere.

Nota che sto utilizzando funzionalità che non sembrano far parte di un'API stabile pubblicata, quindi non è garantito che continuerà a funzionare nelle versioni future di GlassFish.

Ho ottenuto le informazioni su come aggiungere ruoli dal codice sorgente di sun.appserv.security.AppservPasswordLoginModule.commit() di GlassFish. Se una futura release GlassFish rompe il mio codice, questa funzione sarebbe un buon punto di partenza per scoprire come risolverlo.

+2

Soluzione piacevole per una parte del problema. Tuttavia, devo ancora definire i ruoli staticamente nel web.xml. Ma voglio aggiungere ruoli dinamicamente senza dover riavviare il server. Abbiamo finito per farlo in un modo diverso. Non ricordo in dettaglio, ma penso che abbiamo sostituito una grande parte del meccanismo di sicurezza Glassfish con il nostro. – ifischer

+3

Sono d'accordo con ifischer. L'unica vera soluzione è non dover aggiungere nulla in modo statico. Questo dovrebbe essere aggiunto alla specifica in realtà. La dichiarazione forzata potrebbe sembrare una buona idea una volta, ma in pratica è severamente limitante e specialmente in Glassfish agugliato verboso. –

Problemi correlati