2010-02-10 22 views
29

Si entiendo correctamente AccessController.doPrivileged, significa que el código que no es de confianza debe poder invocar los métodos que requieren permisos (como System.getProperty()) a través de un método intermedio que tiene.¿Cuándo se debe usar AccessController.doPrivileged()?

Esto hace surgir la pregunta: ¿cuándo se debe usar AccessController.doPrivileged()? ¿Cuándo se debe permitir que el código que no es de confianza invoque código privilegiado a través de métodos intermedios? ¿Cuándo debería fallar?

Siguiendo su razonamiento, explique por qué la creación cargador de clases siempre se debe permitir: http://findbugs.sourceforge.net/bugDescriptions.html#DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED

Respuesta

16

De acuerdo con Suraj's answer, pero que me gustaría añadir un ejemplo específico en el que he requerido el uso de un bloque privilegiada.

Imagine que ha creado una aplicación que proporciona una serie de servicios para módulos conectables. Entonces, su aplicación y sus servicios son códigos confiables. Sin embargo, los módulos conectables no son necesariamente de confianza y se cargan en sus propios cargadores de clase (y tienen sus propios dominios de protección).

Cuando un módulo conectable invoca un servicio, está implementando comprobaciones de seguridad personalizadas ("el módulo X conectable tiene permiso para usar este servicio"). Pero el servicio en sí podría requerir algún permiso básico de Java (leer una propiedad del sistema, escribir en un archivo, etc.). El código que requiere estos permisos está envuelto en un doPrivileged(), por lo que los permisos insuficientes de los módulos enchufables no confiables se ignoran de manera efectiva; solo se aplican los privilegios de su módulo de servicios de confianza.

+2

@Ash, dado A que tiene permiso para invocar X pero B no lo hace, y A invoca B que invoca X. Does doPrivileged() significa que "B no tiene permiso para invocar X, pero lo hago y respondo por él. Entonces, ¿ahora A puede invocar X "? – Gili

+0

@Gili, tengo entendido que el bloque doPrivileged() asume los permisos del dominio de protección actual, excluyendo todo lo que esté más atrás en la pila. No necesariamente transferirá los permisos hacia adelante a futuras llamadas que tengan permisos menores (estoy trabajando desde la memoria e interpretando la documentación, vea mi comentario en la respuesta de Suraj). – Ash

12
  1. ..through un método intermedio que tiene permisos. No, los permisos efectivos finales son la intersección de todos los permisos en la pila de dominios. Así que supongamos que una operación requiere un permiso B para ejecutarse, y digamos que una LIB intermedia tiene dos permisos B y A. Ahora, cuando algún código no confiable con solo permiso A llama a través de LIB, el conjunto de permisos efectivos es (A intersect (A+B)) = A. Por lo tanto, el código que no es de confianza no puede explotar el LIB intermedio para obtener permisos adicionales.

  2. ¿Cuándo debería usarse doPriveleged? -> Hay muchas operaciones en Java que requieren que el dominio llamante tenga ciertos permisos para la ejecución exitosa de esas operaciones. System.getProperty es una de esas operaciones. Todas las operaciones relacionadas con archivos también necesitan permisos especiales. Cuando utiliza AccessController.doPrivileged para invocar esas operaciones, la operación se ejecuta con todos los derechos (permisos) de su dominio de protección. Por lo tanto, si su código tiene suficientes derechos solo entonces podría ejecutar esas operaciones.

+0

@Suraj, "Cuando utiliza AccessController.doPrivileged para invocar esas operaciones, la operación se ejecuta con todos los derechos (permisos) de su dominio de protección". ¿Puede proporcionar un ejemplo de los permisos con y sin el uso de doPrivileged()? – Gili

+0

@ Gilli ... esto responderá a su pregunta .. "Técnicamente, cada vez que se intenta acceder a un recurso, todo el código atravesado por el subproceso de ejecución hasta ese punto debe tener permiso para acceder a dicho recurso, a menos que se haya marcado algún código en el subproceso como "privilegiado" por un bloque doPriveleged " –

+0

@Gilli ... Supongamos que un hilo atraviesa tres bases de código A, B y C antes de ejecutar una operación segura. A y C no tienen permiso para esa operación, pero B lo hace. Si no usa doPriveleged en B y termina llamando a la operación segura, obtendrá una SecurityException ya que C no tiene suficientes permisos. Pero si usa un bloque doPriveleged en B antes de llamar a C, entonces incluso C también se ejecutará con esos permisos, por lo tanto, ahora puede enviar la operación segura. –

4

Echa un vistazo a estos enlaces y desplázate hacia abajo para utilizar la API doPrivileged.

Java 6: http://docs.oracle.com/javase/6/docs/technotes/guides/security/doprivileged.html

Java 7: http://docs.oracle.com/javase/7/docs/technotes/guides/security/doprivileged.html

Cuando el método AccessController checkPermission es invocado por el llamador más reciente, el algoritmo básico para decidir si se debe permitir o denegar el acceso solicitado es tan sigue:

Si el código para cualquier persona que llama en la cadena de llamadas no tiene el permiso solicitado, se lanza AccessControlException, a menos que lo siguiente sea verdadero: una persona que llama cuyo código obtiene dicho permiso sion ha sido marcada como "privilegiada" (ver abajo) y todas las partes subsecuentemente llamadas por esta persona (directa o indirectamente) tienen dicho permiso

+1

La cita que me llamó la atención es: 'Marcado de código como "privilegiada" permite una pieza de código de confianza para permitir temporalmente el acceso a más recursos que están disponibles directamente al código que lo llamó. Esto es necesario en algunas situaciones.Por ejemplo, una aplicación no puede tener acceso directo a archivos que contienen fuentes, pero la utilidad del sistema para mostrar un documento debe obtener esas fuentes, en nombre del usuario. Para hacer esto, la utilidad del sistema se privilegia al obtener las fuentes. – Gili

7

Esencialmente, AccessController.doPriviledged() es el equivalente de un set-user- archivo de id. Está diciendo "Por este medio solicito que este método se haga con mis privilegios, incluso si fui invocado por un método que no los tiene".

Cuestiones relacionadas