Configuración de políticas para un Applet incrustado en HTML

Diseñé un Applet para tomar una captura de pantalla y guardarla en la computadora de los usuarios usando la clase java.awt.Robot. Necesito insertar este applet en una página html (usando la etiqueta de objeto) para que cuando el usuario haga clic en un botón en la página web se tome la captura de pantalla.

El applet funciona bien, lo he probado agregando un método principal temporal y ejecutándolo en mi máquina local como una aplicación java normal.

Donde tengo dificultades es configurar permisos para permitir que se ejecute desde su ubicación incrustada. Obviamente, la clase de robot es algo peligrosa, por lo que se debe establecer una emisión de AWTP y el applet en sí debe estar firmado.

Seguí el tutorial en http://download.oracle.com/javase/tutorial/security/toolsign/index.html y logré crear un archivo .jar firmado y luego un archivo de política que permitía la aplicación de demostración en ese tutorial para correr. En lo que ahora encuentro problemas es cómo conciliar lo que aprendí con la situación en la que se usará mi applet.

Mi público objective comprende alrededor de 100 máquinas y necesito que sea ejecutable en todas ellas. He empacado mi archivo java .class en .jar y lo he firmado usando keytool y jarsigner. Luego cargué los archivos .jar y .cer en el directorio del servidor donde están alojadas las páginas en cuestión.

Sin embargo: cuando utilicé policytool para crear un nuevo archivo de política en una de las máquinas para probar la configuración, aún no puedo ejecutar la aplicación desde el HTML. Obtengo Java.Security.AccessControlException Acess Denied java.awt.AWTPermission create Robot errors.

Sospecho que es el paso de la política que está yendo mal, así que voy a resumir los pasos que tomé: descargo el certificado a la máquina local y genero un almacén de claves a partir de él, lanzo ‘policytool’ desde este directorio a través de la línea de comandos que agrego el directorio en la máquina local donde se encuentra el almacén de claves generado y mi certificado. Luego presiono el botón agregar política e ingresé el alias SignedBy Luego agregué permisos y seleccioné el objective AWTPermission Targets Seleccioné createRobot El campo de función que he estado dejando en blanco ya que no puedo pensar qué aplicaría aquí. Firmado por en esta ventana también se deja en blanco. presiona ‘Aceptar’ y ‘Hecho’ y recibe una advertencia de que no hay una clave pública para el alias que ingresé en el primer paso. Hago un ‘guardar como’ y guardo mi archivo de políticas en el mismo directorio en el que coloco el certificado y el almacén de claves generado a partir de él.

Sin embargo, esto no me permite ejecutar el applet desde la página web y mi comprensión limitada de este aspecto de la progtwigción no ofrece pistas sobre lo que salió mal.

Ideas, pensamientos, observaciones? Si no he mencionado algo explícitamente, entonces no lo he hecho. Mi mayor sospecha es la advertencia que recibo, pero no puedo encontrar por qué aparece

EDITAR: se olvidó de mencionar un paso. Agregué manualmente a mi archivo jre \ lib \ security \ java.security la línea ‘policy.url.3 = file: / C: / Testing / debugpolicy’ ya que esa es la ruta y el nombre de archivo de la política que creé durante los pasos anteriores. También me las arreglé para eliminar la advertencia que mencioné anteriormente, había estado mezclando mi alias ‘y dado el alias para el almacén de claves privado en lugar del público durante la creación del archivo de políticas, sin embargo, todavía encuentro los mismos problemas

Si un applet está firmado correctamente, no se requiere ningún archivo de política, ni se requiere cargar ningún certificado por separado. Un applet correctamente firmado solicitará permiso al usuario cuando se visite el applet, antes de que se cargue. ¿Aparece el mensaje?

Aquí hay una pequeña demostración. Escribí que demuestra la carga defensiva de los applets de confianza . Ese es el mensaje de seguridad al que me refiero.

Si el applet está firmado digitalmente por el desarrollador y es de confianza para el usuario final, debería poder tomar una captura de pantalla.

Hay otra cosa que puedes probar si el applet es de confianza, solo como un experimento (1). Al principio de la aplicación init() , llame a System.setSecurityManager(null) . Eso probará si el applet tiene confianza y eliminará los últimos remanentes del administrador de seguridad “de confianza” que se les da a los applets.

Y en el caso de que eso funcione, y hace que la captura de pantalla sea exitosa, sugiere que un error u Oracle cambiaron de opinión sobre los valores predeterminados de lo que un applet de confianza podría hacer.

1) No hagas esto en un mundo real o en un entorno de producción. Para citar a Tom Hawtin:

Esta pregunta parece haber dado la impresión de que se llama a System.setSecurityManager(null); está bien. … En caso de que alguien tenga alguna duda, cambiar el estado global en un applet afectará a todos los applets en el mismo proceso. Borrar el administrador de seguridad permitirá que cualquier applet sin firmar haga lo que quiera. No firme código que se reproduce con estado global con un certificado en el que espera que alguien confíe.


Edición 1: Aquí está la fuente del applet simple usado en esa demostración. Por alguna razón, cuando originalmente lo cargué, decidí que la fuente no era relevante. OTOH 3 personas ahora han pedido ver la fuente, por una razón u otra. Cuando reciba una ronda tuit subiré la fuente a mi sitio. Mientras tanto, lo pondré aquí.

 package org.pscode.eg.docload; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.*; import java.security.*; /** An applet to display documents that are JEditorPane compatible. */ public class DocumentLoader extends JApplet { JEditorPane document; @Override public void init() { System.out.println("init()"); JPanel main = new JPanel(); main.setLayout( new BorderLayout() ); getContentPane().add(main); try { // It might seem odd that a sandboxed applet can /instantiate/ // a File object, but until it goes to do anything with it, the // JVM considers it 'OK'. Until we go to do anything with a // 'File' object, it is really just a filename. File f = new File("."); // set up the green 'sandboxed page', as a precaution.. URL sandboxed = new URL(getDocumentBase(), "sandbox.html"); document = new JEditorPane(sandboxed); main.add( new JScrollPane(document), BorderLayout.CENTER ); // Everything above here is possible for a sandboxed applet // *test* if this applet is sandboxed final JFileChooser jfc = new JFileChooser(f); // invokes security check jfc.setFileSelectionMode(JFileChooser.FILES_ONLY); jfc.setMultiSelectionEnabled(false); JButton button = new JButton("Load Document"); button.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent ae) { int result = jfc.showOpenDialog( DocumentLoader.this); if ( result==JFileChooser.APPROVE_OPTION ) { File temp = jfc.getSelectedFile(); try { URL page = temp.toURI().toURL(); document.setPage( page ); } catch(Exception e) { e.printStackTrace(); } } } } ); main.add( button, BorderLayout.SOUTH ); // the applet is trusted, change to the red 'welcome page' URL trusted = new URL(getDocumentBase(), "trusted.html"); document.setPage(trusted); } catch (MalformedURLException murle) { murle.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (AccessControlException ace) { ace.printStackTrace(); } } @Override public void start() { System.out.println("start()"); } @Override public void stop() { System.out.println("stop()"); } @Override public void destroy() { System.out.println("destroy()"); } }