Programación en castellano
Inicio > Tutoriales > J2SE > Seguridad en la Plataforma Java 2 JDK 1.2
-Tutoriales

Seguridad en la Plataforma Java 2 JDK 1.2


Implementar Nuestros Propios Permisos

Esta lección desmuestra cómo escribir una clase que defina nuestro propio permiso especial. Los componentes básicos de esta lección incluyen.

  1. Un programa de ejemplo llamado TerrysGame.
  2. Una clase llamada HighScore, que es usada por TerrysGame para almacenar los últimos valores más altos del usuario.
  3. Una clase llamada HighScorePermission, que es usada para proteger el acceso del usuario a los valores máximos almacenados.
  4. Un fichero de polícia de usuario, que concede permiso a TerrysGame para actualizar las puntuaciones.

El escenario básico es el siguiente.

  1. Un usuario juega a TerrysGame.
  2. Si el usuario alcanza la puntuación más alta, TerrysGame usa la clase HighScore para grabar el nuevo valor.
  3. La clase HighScore busca en el fichero de política del usuario para ver si TerrysGame tiene permiso para actualizar las puntuaciones del usuario.
  4. Si TerrysGame tiene el permiso, la clase HighScore actualiza el resultado.

Describiremos los puntos claves de cada uno de los componentes básicos y luego veremos un ejemplo de ejecución.

. TerrysGame

Abajo está el código fuente de TerrysGame. Por simplicidad, TerrysGame ahora no contiene código para jugar. Simplemente recupera y actualiza las puntuaciones máximas del usuario.

Para ver la máxima puntuación del usuairo, podremos ejecutar.

java TerrysGame get

Para ver el nuevo valor de la maxima puntuación del usuario, podemos ejecutar.

java TerrysGame set score 

Para recuperar la máxima puntuación actual del usuario, TerrysGame simplemente ejemplariza un objeto HighScore y hace que llame a su método getHighScore. Para ver una nueva puntuación máxima del usuario, TerrysGame ejemplariza un objeto HighScore y llama a setHighScore, pasándole la nueva puntuación máxima del usuario.

Aquí está el código fuente de TerrysGame, TerrysGame.java.

package com.gamedev.games;

import java.io.*;
import java.security.*;
import java.util.Hashtable;
import com.scoredev.scores.*;

public class TerrysGame
{
    public static void main(String args[])
	throws Exception 
    {
	HighScore hs = new HighScore("TerrysGame");

	if (args.length == 0)
	    usage();

	if (args[0].equals("set")) {
	    hs.setHighScore(Integer.parseInt(args[1]));
	} else if (args[0].equals("get")) {
	    System.out.println("score = "+ hs.getHighScore());
	} else {
	    usage();
	}
    }

    public static void usage()
    {
	System.out.println("TerrysGame get");
	System.out.println("TerrysGame set <score>");
	System.exit(1);
    }
}

. La Clase HighScore

La clase HighScore almacena y protege el acceso a la máxima puntuación del usuario de TerrysGame (y de cualquier otro juego que la llame). Por simplicidad, esta clase graba la máxima puntuación en un fichero, llamado .highscore, en el directorio home del usuario. Sin embargo, antes de permitir a TerrysGame que recupere y actualice el valor de máxima puntuación del usuario, esta clase chequea para asegurarse de que el usuario ha concedido a TerrysGame el permiso para acceder a la máxima puntuación en su fichero de política de seguridad.

. Comprobar que TerrysGame tiene el HighScorePermission

Para comprobar si TerrysGame tiene o no permiso para acceder a la máxima puntuación del usuario, la clase HighScore debe.

  1. Llamar a System.getSecurityManager() para obtener el controlador de seguridad instalado realmente.
  2. Si el resultado no es null (es decir, es un controlador de seguridad, lo opuesto a cuando el llamador es una aplicación que no tiene restricciones), entonces
    1. Construye un objeto HighScorePermission, y
    2. llama al método checkPermission del controlador de seguridad, y el pasa el objeto HighScorePermission recientemente construido.

Aquí está el código.

SecurityManager sm = System.getSecurityManager();
if (sm != null) {
    sm.checkPermission(new HighScorePermission(gameName));
}

Esencialmente el método checkPermission lepreginta al controlador de seguridad si TerrysGame tiene el HighScorePermission especificado. En otras palabras, le pregunta al controlador de seguridad si TerrysGame tiene permiso para actualizar la máxima puntuación del usuario para el juego específicado (TerrysGame). El marco de trabajo de seguridad en segundo plano consultará el fichero de política del usuario para ver si realmente TerrysGame tiene este permiso.

. El código HighScore

Aquí está el código fuente completo de la clase HighScore.

Nota: las llamadas al método doPrivileged se utilizan para permitir a HighScore un acceso temporal a los recursos que tiene disponibles, pero no está disponible para el código que llamó a (TerrysGame). Por ejemplo, espera que el fichero de política conceda permiso a HighScore para acceder al fichero .highscore en el directorio home del usuario, pero no concede este permiso a los juegos, como TerrysGame. Para más información sobre el uso de los métodos doPrivileged puedes visitar New Privileged Block API en la web site de java.sun.com.

. La clase HighScorePermission

La clase HighScorePermission define el permiso que TerrysGame necesita para actualizar la máxima puntuación del usuario.

Todas las clases permission tienen que ser una subclase de java.security.Permission o de java.security.BasicPermission. La diferencia básica entre las dos es que java.security.Permission define permisos más complejos que requieren nombres y acciones. Por ejemplo, un java.io.FilePermission desciende de java.security.Permission, y requiere un nombre (un nombre de fichero) y las acciones permitidas para ese fichero (leer/escribir/borrar).

En contraste, java.security.BasicPermission define permisos sencillos que sólo requieren un nombre. Por ejemplo, java.lang.RuntimePermission desciende de java.security.BasicPermission y sólo necesita un nombre (como "exitVM"), que permite a los programas salir de la Maquina Virtual Java.

Nuestro HighScorePermission es un permiso sencillo, y de hecho puede descender de java.security.BasicPermission.

Frecuentemente, la implementación de los métodos de la propia clase BasicPermission no tiene que ser sobreescrita por sus subclases. Este es el caso de nuestro HighScorePermission, por eso todo lo que tenemos que implementar son los constructores, que sólo invocan a los constructores de la superclase, como se ve en el código.

package com.scoredev.scores;

import java.security.*;

public final class HighScorePermission extends BasicPermission {

    public HighScorePermission(String name)
    {
	super(name);
    }

    // note that actions is ignored and not used,
    // but this constructor is still needed
    public HighScorePermission(String name, String actions) 
    {
	super(name, actions);
    }
}

. Un Fichero de Política de Ejemplo

Abajo hay un fichero de política completo usado por un usuario que está esperando para ejecutar TerrysGame.

La síntaxis del fichero de política no se describe aquí; si estás interesado puedes ver Default Policy Implementation and Policy File Syntax en el web site de java.sun.com.

No necesitamos conocer la síntaxis, siempre podemos usar Policy Tool para crear ficheros de política, como se muestra en las lecciones Visión Rápida para Controlar Applets, Visión Rápida para Controlar Aplicaciones, y Firmar Código y Conceder Permisos.

Abajo está el fichero de política de ejemplo, seguida por una descripción de las entradas individuales. Asume que.

  • El fichero de política está en el ordenador de Kim, y su keystore se llama kim.keystore.
  • TerrysGame ha sido firmado por la clave privada de Terry, su creador, y la correspondiente clave pública está en el keystore con el alias de "terry".
  • Las clases HighScore y HighScorePermissions fueron firmadas con la clave privada de la persona que las implementó (Chris), y su correspondiente clave pública está en el keystore con el alias de "chris".

Aquí está el fichero de política.

keystore "kim.keystore";

// Here is the permission TerrysGame needs.
// It grants code signed by "terry" the HighScorePermission, if the
// HighScorePermission was signed by "chris"
grant SignedBy "terry" {
  permission com.scoredev.scores.HighScorePermission
      "TerrysGame", signedBy "chris";
};

// Here is the set of permissions the HighScore class needs.
grant SignedBy "chris" {
  // The HighScore class needs permission to read "user.home" to find
  // the location of the highscore file

  permission java.util.PropertyPermission "user.home", "read";

  // It needs permission to read and write the high score file itself

  permission java.io.FilePermission
      "${user.home}${/}.highscore", "read,write";

  // It needs to get granted its own permission,
  // so it can call checkPermission
  // to see if its caller has permission.
  // Only grant it the permission
  // if the permission itself was signed by "chris"

  permission com.scoredev.scores.HighScorePermission 
      "*", signedBy "chris";
};

. La Entrada Keystore

Un keystore es un repositorio de claves y certificados, y se usa para buscar las claves públicas de los firmantes especificados en el fichero de política ("terry" y "chris" en este ejemplo).

La utilidad keytool se utiliza para crear y administrar keystores.

Para esta lección, asumimos que Kim quiere jugar a TerrysGame. Si el keystore de Kim tiene el nombre de kim.keystore, el fichero de política de Kim necesita tener la siguiente línea lo más al principio posible.

keystore "kim.keystore";

. La Entrada TerrysGame

Una entrada de fichero de política especifica uno o más permisos para el código de un código fuente particular - o bien código de una localización particular (URL) o código firmado por una entidad particular o ambos.

Nuestro fichero de política necesita una entrada para cada juego, concediendo al código firmado por el creador del juego un HighScorePermission cuyo nombre es el nombre del juego. Este permiso permite al juego llamar a los métodos HighScore para obtener o actualizar el valor de la máxima puntuación de un usuario en un juego particular.

La entrada requerida para TerrysGame es.

grant SignedBy "terry" {
  permission com.scoredev.scores.HighScorePermission 
      "TerrysGame", signedBy "chris";
};

Requerir que el juego TerrysGame esté firmado por "terry" permite a Kim saber que el juego es realmente el juego que desarrolló Terry. Para este trabajo, Kim debe terner almacenado el certificado de la clave pública de Terry en kim.keystore usando el alias "terry".

Observa que HighScorePermission necesita estar firmado por "chris", la persona que realmente implementó el permiso. Esto asegura que a TerrysGame se le concede el permiso que realmente implementó "chris", y no el de otra persona. Como antes, para hacer esto Kim debe tener almacenado el certificado de la clave pública de Chris en kim.keystore usando el alias "chris".

. La Entrada HighScore

La entrada final del fichero de política concede permiso a la clase HighScore. Más específiamente concede permiso al código firmado por "chris", que fue quien creo y firmó la clase. Requiriendo que la clase esté firmada por "chris" aseguramos que cuando TerrysGame llama a esta clase para actualizar la puntuación máxima del usuario, TerrysGame da por seguro que está suando la clase original implementada por "chris".

Para actualizar el valor de la puntuación máxima del usuario por cualquier juego que lo llame, la clase HighScore requiere tres permisos.

. 1. Permiso para leer el valor de la propiedad "user.home".

La clase HighScore almacena la puntuación máxima del usuario en un fichero .highscore en el directorio home del usuario. Por lo tanto está clase necesita un java.util.PropertyPermission que le permita leer el valor de la propiedad "user.home" para encontrar exáctamente dónde se encuenra el directorio home del usuario.

permission java.util.PropertyPermission 
    "user.home", "read";

. 2. Permiso para leer y escribir el propio fichero de la máxima puntuación.

Este permiso se necesita porque los métodos getHighScore y setHighScore pueden acceder al fichero del usuario .highscore para obtener o seleccionar, respectivamente, el valor actual de la máxima puntuación del usuario en el juego actual.

Aquí está el permiso requerido.

permission java.io.FilePermission
    "${user.home}${/}.highscore", "read,write";

Nota: la notación ${propName} específica el valor de una propiedad. Así, ${user.home} será reempalzao por el valor de la propiedad "user.home". La notación ${/} es una forma independiente de la plataforma de identificar un separador de ficheros.

. 3. Todos los HighScorePermissions (es decir, HighScorePermissions de cualquier nombre).

Este permiso es necesario para que la HighScore se asegure de que el juego llamante tiene concedido un HighScorePermission cuyo nombre es el nombre del juego para el que trabaja. Es decir, la clase HighScore también debe conceder este permiso, ya que un chequeo de permiso requiere que todo el código que hay en la pila tenga el permiso específicado.

Aquí está el permiso requerido.

permission com.scoredev.scores.HighScorePermission
    "*", signedBy "chris";

Como antes, el propio HighScorePermission necesita estar firmado por "chris", la persona que realmente implementó el permiso.

. Poniéndolo Todo Junto

Aquí, hemos simulado ser, por turnos, el desarrallador de HighScore (Chris), el desarrollador de TerrysGame (Terry), y el usuario del juego (Kim).

Podemos ejecutar todos los pasos específicados, y luego jugar con TerrysGame.

Los pasos se presentan sin explicación, Para más informaicón sobre los pasos necesarios tomados por los firmantes de código (como Chris y Terry) y por los receptores de código (como Kim), puedes ver la lección: Firmar Código y Concerderle Permisos.

Aquí están los pasos.

. Pasos del Desarrollador de HighScore (Chris)

Los pasos que Chirs debería realizar, después de crear las clases HighScore y HighScorePermission, son.

. Compilar las Clases

javac HighScore*.java -d .

. Meter los ficheros class en un fichero JAR

jar cvf hs.jar com/scoredev/scores/HighScore*.class

. Crear un Keystore y las Claves para Firmar

keytool -genkey -keystore chris.keystore -alias signJars

Podemos especificar las passwords que queramos y la información de nombre distinguido.

. Firmar el fichero JAR

jarsigner -keystore chris.keystore hs.jar signJars

. Exportar el Certificado de la Clave Pública

keytool -export -keystore chris.keystore
    -alias signJars -file Chris.cer

. Suministrar los Ficheros y la Información Necesaria para los Usuarios y Desarrolladores del Juego

Esto es, suministrarles

  • El fichero JAR firmadohs.jar,
  • el fichero del certificado de la clave pública Chris.cer, y
  • y la información sobre los permisos que deben concederse en el fichero de política a las clases HighScore y HighScorePermission para poder funcionar. Para esto, Chirs debería suministrar la entrada de permiso exacta necesaria.

. Pasos del Desarrollador de TerrysGame (Terry)

Los pasos que Terry debería realizar, despúes de crear el juego (TerrysGame ) las llamadas a los métodos getHighScore y setHighScore de HighScore, son.

. Compilar la Clase del Juego

javac TerrysGame.java -classpath hs.jar -d .

. Poner sus ficheros Class en un fichero JAR

jar cvf terry.jar com/gamedev/games/TerrysGame.class

. Crear un Keystore y las Claves para Firmar

keytool -genkey -keystore terry.keystore -alias signTJars

Podemos especificar las passwords que queramos y la información de nombre distinguido.

. Firmar el Fichero JAR

jarsigner -keystore terry.keystore terry.jar signTJars

. Exportar el Certificado de la Clave Pública

keytool -export -keystore terry.keystore
    -alias signTJars -file Terry.cer

. Suministrar los Ficheros y la Información Necesaria para los Usuarios

Es decir, suministrales

  • El fichero JAR firmadoterry.jar,
  • el fichero del certificado de la clave pública terry.cer, y
  • y la información sobre los permisos que deben concederse en el fichero de política a las clases TerrysGame y HighScorePermission para poder funcionar. Para esto, Chirs debería suministrar la entrada de permiso exacta necesaria.

Lo usuarios del Juego también necesitarán la información de Chris. Por conveniencia, Terry podría reenviarles está información.

  • El fichero JAR firmadohs.jar,
  • el fichero del certificado de la clave pública Chris.cer, y
  • y la información sobre los permisos que deben concederse en el fichero de política a las clases HighScore y HighScorePermission para poder funcionar. Para esto, Chirs debería suministrar la entrada de permiso exacta necesaria.

. Pasos para Ejecutar TerrysGame (Kim)

Los pasos que un usuario, como Kim, debería realizar son.

. Importar los Certificados como Certificados Verdaderos

keytool -import -alias chris -file Chris.cer -keystore kim.keystore
keytool -import -alias terry -file Terry.cer -keystore kim.keystore

. Configurar un fichero de Política con los Permisos Requeridos

Aquí está el fichero de política kim.policy, como se describió en "Un Fichero de Política de Ejemplo".

. Ejecutar el TerrysGame

Para seleccionar la puntuación máxima.

java -Djava.security.manager -Djava.security.policy=kim.policy
 -classpath hs.jar;terry.jar com.gamedev.games.TerrysGame set 456

Para obtener la máxima puntuación.

java -Djava.security.manager -Djava.security.policy=kim.policy
 -classpath hs.jar;terry.jar com.gamedev.games.TerrysGame get

Notas.

  • Si no especificamos -Djava.security.manager, la aplicación se ejecutará sin restricciones (no se chequearán los ficheros de política ni los permisos
  • -Djava.security.policy=kim.policy dice donde se encuentra el fichero de política.

    Nota: Existen otras formas de especificar el fichero de política. Por ejemplo, podemos añadir una netrada en el fichero de propiedades de seguridad que especifique la inclusión del kim.policy, como se explica al final de la lección Ver los Efectos del Fichero de Política.

  • -classpath hs.jar;terry.jar especifica los ficheros JAR que contienen los ficheros class necesarios. En Windows se usa un punto y coma (";") para separar los ficheros JAR, en Unix se usan dos puntos (":").
  • El fichero de política kim.policy especifica el keystore kim.keystore. Como no se proporciona la localizaicón URL del keystore, se asume que se encuentra en el mismo directorio que el fichero de política.
 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: musica mp3 | logos y melodias | hospedaje web linux | registro de dominios | servidores dedicados
más internet: comprar | recursos gratis | posicionamiento en buscadores | tienda virtual | gifs animados