2011-09-27 14 views
22

Cómo restringir a los desarrolladores el uso de la reflexión para acceder a métodos privados y constructores en Java?Cómo restringir a los desarrolladores el uso de la reflexión para acceder a métodos privados y constructores en Java?

Utilizando el código Java normal no podemos acceder a constructores privados o métodos privados fuera de una clase. Pero al usar la reflexión podemos acceder a cualquier método y constructor privado en una clase Java.

Entonces, ¿cómo podemos dar seguridad a nuestro código de Java?

+0

Esta sería una buena opción para tener frascos firmados. "Bajo ninguna circunstancia, permita la reflexión contra las clases en este archivo jar". Pero creo que no hay tal característica. – Thilo

Respuesta

2

Usted (como desarrollador del código en cuestión) no puede hacer eso.

El usuario final, que ejecuta la aplicación, podría instalar un SecurityManager que prohíbe la reflexión.

+0

Por supuesto que puede. Instala el administrador de seguridad durante el inicio de su aplicación. –

+0

No es una opción a menos que sea el desarrollador de la aplicación. Estaba pensando más en el caso en el que "quiere restringir a los desarrolladores [presumiblemente de la aplicación] el uso de la reflexión" contra los métodos que le gustaría mantener en privado. – Thilo

+0

¿Qué le impide tener un inicializador estático en sus clases que instale un administrador de seguridad? ¿Y por qué tiene una excepción que previene la laoding de clases, si no puede instalarlo? –

6

Agregue el método checkPermission() en todo su método/constructor privado. checkPermission usando sun.reflect.Reflection.getCallerClass(int n) por la afirmación callerClass=selfClass.

getCallerClass devuelve la clase del método realFramesToSkip fotogramas de la pila (basada en cero), ignorando las tramas asociadas con java.lang.reflect.Method.invoke() y su implementación. El primer fotograma es el asociado a este método, por lo que getCallerClass(0) devuelve el objeto Clase para sun.reflect.Reflection.

public class PrivateConstructorClass { 

    private PrivateConstructorClass() { 
     checkPerMission(); 
       //you own code go below 
    } 

    void checkPerMission() { 
     Class self = sun.reflect.Reflection.getCallerClass(1); 
     Class caller = sun.reflect.Reflection.getCallerClass(3); 
     if (self != caller) { 
      throw new java.lang.IllegalAccessError(); 
     } 
    } 
} 

Usted puede tratar de probar reflejan, se producirá un error:

public class TestPrivateMain { 

    Object newInstance() throws Exception { 

     final Class<?> c = Class.forName("package.TestPrivate"); 

     final Constructor<?> constructor = c.getDeclaredConstructor(); 
     constructor.setAccessible(true); 
     return constructor.newInstance(); 

    } 

    public static void main(String[] args) throws Exception { 
     Object t = new TestPrivateMain().newInstance(); 
    } 
} 
+2

-1: para llamar a "APIs" inestables como sun.reflect.Reflection ... –

+2

Hmm ... Pero fue un buen intento, de hecho, en mi opinión ... Las API inestables no deberían estar allí en primer lugar –

Cuestiones relacionadas