2010-09-30 8 views
9

Estoy desarrollando una aplicación Java EE 6 utilizando Glassfish 3.1, B06. Para asegurar mi aplicación, estoy usando un JDBCRealm y seguridad programática. Esto funciona bien para verificar el nombre de usuario y la contraseña. Pero cuando se trata de declarar roles de seguridad, tengo un problema:Agregar roles de seguridad de Java EE dinámicamente sin usar el descriptor de implementación

Para usar Roles de seguridad en Java EE 6, tengo que declarar esos roles tanto en el descriptor de despliegue EJB como en el descriptor de despliegue específico de Glassfish para vincularlos roles (como se explica en el Java EE 6-tutorial) Solo que puedo usar el método isCallerInRole (String roleRef) dentro de un EJB para comprobar los permisos.

Esto no es deseable para mi aplicación, ya que quiero que sea posible agregar funciones de seguridad tanto de forma dinámica como programática, sin tener que escribir archivos XML (y por ejemplo permitir definir nombres de roles en una base de datos).

acabo depurado a través del código GF3-fuente y se inició la aplicación de isCallerInRole en com.sun.ejb.containers.EjbContextImpl. Allí el recipiente se pone el papel del descriptor de EJB:

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

Miré a mi alrededor y descubrí que si de alguna manera podría conseguir el descriptor de EJB dentro de mi solicitud, yo podría agregar una función como esta:

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); 

¿Alguien hizo algo así o tiene alguna opinión al respecto? ¿Es posible usar el descriptor de despliegue Ejb dentro de mi aplicación? ¿O hay mejores enfoques?

P.S. o debería usar MBeans para agregar Roles? Encontré una publicación bastante relacionada here.

+1

Como comentario adicional, le animo a pasar a una compilación más reciente de GlassFish Server 3.1. El equipo lanzó recientemente construir 22. – vkraemer

+0

Gracias. Desafortunadamente, tenemos algunas bibliotecas que se rompen en las versiones más altas de Glassfish, así que tenemos que seguir con 06 hasta que se solucionen varios errores en estas librerías. – ifischer

Respuesta

3

El Javadoc menciona explícitamente este requisito:

/** 
    * 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); 

Sin embargo, he encontrado que al menos con JBoss ya que no es necesario en absoluto para declarar esos papeles con antelación. En nuestro caso, los roles principales se crean dinámicamente en el sistema y se asignan cuando tiene lugar la autenticación. Por lo tanto, es imposible declararlos por adelantado.

Sin embargo, el método isCallerInRole funciona perfectamente bien.

Me doy cuenta de que cambiar a JBoss AS no es una solución, pero tal vez esta información sea valiosa para alguien de todos modos.

3

me ocurrió con la siguiente solución para agregar funciones mediante programación después de iniciar sesión, que funciona al menos en GlassFish 3.1.2 build 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); 
    } 
} 

Usted tendrá que añadir security.jar y common-util.jar de GlassFish a su proyecto bibliotecas.

Y no olvide crear una sección <security-role> en su web.xml para los roles que desea agregar.

Tenga en cuenta que estoy utilizando una funcionalidad que no parece ser parte de una API estable publicada, por lo que no hay garantía de que esto seguirá funcionando en futuras versiones de GlassFish.

Obtuve la información sobre cómo agregar roles desde el código fuente de sun.appserv.security.AppservPasswordLoginModule.commit() de GlassFish. Si un futuro lanzamiento de GlassFish rompe mi código, esta función sería un buen lugar para comenzar a fin de descubrir cómo solucionarlo.

+2

Buena solución para una parte del problema. Sin embargo, todavía tengo que definir los roles estáticamente dentro de web.xml. Pero quiero agregar roles dinámicamente sin tener que reiniciar el Servidor. Terminamos haciéndolo de una manera diferente. No recuerdo con detalle, pero creo que reemplazamos una gran parte del mecanismo de seguridad de Glassfish con el nuestro. – ifischer

+3

Estoy de acuerdo con ifischer. La única solución real es no tener que agregar nada estáticamente. Esto debería agregarse a la especificación realmente. La declaración forzada podría parecer una buena idea una vez, pero en la práctica es severamente limitante y especialmente en Glassfish. –

Cuestiones relacionadas