Download Seguridad Empresarial en Java - unsj

Document related concepts
no text concepts found
Transcript
7tWXOR6HJXULGDGHPSUHVDULDOHQ-DYD
$XWRUHV
Ortega, Manuel Oscar - [email protected]
Frias, Natalia
- [email protected]
Rodríguez, Nelson
- [email protected]
Docentes e investigadores del Departamento de Informática, de la Facultad de Ciencias Exactas,
Físicas y Naturales de la Universidad Nacional de San Juan.
3UR\HFWRGH,QYHVWLJDFLyQ
Entorno para la construcción de evaluacióon en Red.
,QWURGXFFLyQ
Los sistemas empresariales frecuentemente son entornos de computación distribuida a gran
escala que implementan una funcionalidad vital para el funcionamiento de una empresa u
organización. Asegurar el sistema empresarial distribuido es, por tanto, una preocupación
fundamental para las empresas y organizaciones que deseen mantener seguridad en sus
operaciones clave. Las tecnologías de sistemas empresariales Java de la plataforma Java 2
Edición Empresarial (J2EE), se emplean hoy en día en los sistemas empresariales para proteger
las operaciones clave (los datos, las comunicaciones, la Web y las aplicaciones) de una empresa.
Un conjunto de mecanismos de seguridad empresarial estándar que complementan estas
tecnologías también se proporciona tanto en los entornos empresariales Java como en los
entornos J2EE.
Este trabajo ofrece una introducción a:
• Las tecnologías de sistemas empresariales Java más importantes.
• La provisión de la seguridad en la conectividad empresarial de base de datos Java.
• La provisión de seguridad en los en los paradigmas de comunicación empresarial de Java.
• La provisión de la seguridad sobre servicios de comunicación empresarial Java.
• La provisión de seguridad de los componentes EJB y Web basados en contenedores Java.
7HFQRORJtDGHVLVWHPDVHPSUHVDULDOHVGLVWULEXLGRV
Los sistemas empresariales abarcan algunos sistemas distribuidos, escalables, multiusuario que
están íntimamente relacionados con la mejora de la productividad de una empresa u
organización a través de la tecnología de la información. Cada vez más, las empresas y
organizaciones se están comprometiendo en una red informativa compleja en un esfuerzo por
mejorar la productividad de sus operaciones por motivos de competitividad y de reducción de
costos. El comercio electrónico, Internet/Web, la conectividad de negocio a negocio (B2B), la
integración de aplicaciones empresariales (EAI), y la extracción de datos son sólo unos cuantos
requisitos que deben ser satisfechos por diseños de sistemas empresariales. Las tecnologías
empresariales Java y la plataforma Java 2 Edición Empresarial (J2EE), en particular, ofrecen
una solución a la construcción más efectiva y rápida de sistemas empresariales que puedan
generar software empresarial reutilizable, escalable, distribuible, mantenible, seguro, fiable y
disponible.
En esta sección analizaremos brevemente las tecnologías de sistemas empresariales Java, de
forma que pueda comprender mejor los mecanismos de seguridad específicos que proporcionan
estas tecnologías.
En este trabajo, dividiremos el problema de los sistemas empresariales distribuidos en cuatro
categorías principales:
• Conectividad empresarial de base de datos: proporciona una forma de acceder a los datos
almacenados en una base de datos.
1
•
•
•
Comunicaciones empresariales: proporciona una forma de comunicarse entre procesos
distribuidos por una red.
Servicios empresariales de comunicación: proporcionan servicios comunes construidos
sobre un paradigma de comunicaciones distribuidas empleadas por aplicaciones
empresariales, independientemente del dominio de aplicación de que se trate.
Componentes empresariales basados en contenedores: proporcionan paradigmas de
programación del lado del servidor que permiten a los desarrolladores centrarse en tareas de
desarrollo de componentes específicas de la aplicación, al tiempo que utilizan una
infraestructura de contenedor/servidor para administrar el ciclo de vida y la configuración
de tales componentes.
&RQHFWLYLGDGHPSUHVDULDOGHEDVHGHGDWRV
El acceso a almacenes de datos empresariales es extremadamente importante para la
construcción de sistemas empresariales. Existe una gran variedad de formas para conectar
aplicaciones empresariales Java con datos empresariales almacenados en bases de datos, pero la
API Java DataBase Connectivity, (JDBC), es la estructura de datos empresariales más común y
rica en prestaciones de Java. JDBC constituye una parte de J2EE y ha sido utilizada con mucha
frecuencia por las organizaciones en su versión JDBC 1.x que se incluye en el JDK v1.1. JDBC
2.0 ofrece nueva funcionalidad al núcleo del J2EE y unas cuantas extensiones importantes
específicas de la empresa en el J2EE.
El desarrollo básico de JDBC implica el uso de la API JDBC con un controlador JDBC
asociado que manipula la conexión de la base de datos concreta que le interese. La API JDBC se
emplea para solicitar un puntero a una conexión de base de datos a partir del controlador JDBC.
La conexión JDBC puede utilizarse entonces para crear instrucciones SQL, instrucciones
preparadas o llamadas a procedimientos almacenados. Cuando se consultan datos, se devuelve
un conjunto de resultados JDBC que se puede usar para obtener datos de las bases de datos. Las
opciones avanzadas de JDBC 2.0 le permiten examinar esos conjuntos de resultados de un modo
más flexible, llevar a cabo actualizaciones directamente desde el conjunto de resultados, y
realizar actualizaciones por lotes en la base de datos. Además, ahora se puede manipular una
amplia gama de tipos de SQL avanzados con JDBC 2.0. Por último, la especificación JDBC 2.0
define estándares para fabricantes de PLGGOHZDUH para el volcado de conexión de base de datos
y la administración de recursos de transacciones distribuidas.
&RPXQLFDFLRQHVHPSUHVDULDOHV
La transferencia y la recepción de información empresarial en computadoras de la empresa es
una consideración a tener en cuenta en cualquier tarea de desarrollo de sistemas empresariales.
Proporcionar una solución de computación empresarial normalmente implica ofrecer una
solución en la que pueda interoperar y comunicar una gama heterogénea y, a menudo, dispersa
de plataformas y dispositivos de computación por las distintas redes de comunicación que
conectan la empresa. Además, a medida que se van añadiendo plataformas y dispositivos de
computación a la empresa, las comunicaciones empresariales, así como los sistemas de software
de aplicaciones, deberán aumentar para satisfacer la demanda creciente en la red.
El soporte estándar basado en Java se da en tres paradigmas clave de comunicación empresarial
distribuida:
• Redes TCP/IP básicas: las comunicaciones de red de los sistemas empresariales son
TCP/IP, representa el protocolo de comunicaciones fundamental que utilizan la mayoría de
los paradigmas de comunicaciones empresariales Java. La programación de sockets ofrece
una API a las pilas de protocolos TCP/IP. La plataforma Java incorpora en el paquete
java.net una serie de API´s estándar de programación de sockets basadas en Java. Una clase
Socket encapsula un marcador básico de un socket TCP/IP , mientras que se utiliza una
clase ServerSocket para crear sockets de servidor TCP/IP. Las bibliotecas de sockets Java
2
•
•
pueden ser personalizadas para implementar protocolos modularmente por TCP/IP
utilizando clases e interfaces, como SocketImplFactory.
RMI: la plataforma Remote Method Invocation, es un modelo de comunicaciones de objetos
distribuidos centrados en Java. Al usar los paquetes e infraestructura RMI, los clientes Java
basados en RMI pueden invocar remotamente métodos sobre los objetos del servidor Java
basados en RMI. RMI permite a los clientes y servidores pasar objetos como parámetros de
método y devolver valores por valor o referencia. Si una clase utilizada como parámetro de
método o de retorno es desconocida para el cliente o el servidor, podrá ser cargado
dinámicamente utilizando especificaciones RMI. Aunque los objetos servidor pueden
construirse y enlazarse explícitamente en el lado del servidor en un servicio de búsqueda,
los objetos servidor también se podrán activar automáticamente a petición del cliente sin
instancia previa alguna del objeto del lado del servidor. RMI puede operar con TCP/IP a
través de un protocolo específico de Java llamado Java Remote Method Protocol (JRMP), o
a través de un protocolo de estándares abiertos, conocido como Internet Inter-ORB Protocol
(IIOP).
CORBA: la Common Object Request Broker Architecture, es un cuerpo de especificaciones
neutral al lenguaje y a la plataforma que sirve para construir aplicaciones de objetos
distribuidos creados por el consorcio de empresas Object Management Group. Las
aplicaciones CORBA se construyen para ser ampliamente aisladas de los detalles del código
del código de comunicaciones. Los objetos Common Object Services Specification
(CORBAservices), Common Facilities Architecture (CORBAfacilities), y los objetos de
negocios CORBA son todos ellos estándares construidos sobre CORBA que proporcionan
un paquete muy rico de servicios y estructuras de comunicación distribuida. El CORBA
Interface Definition Language (IDL), ofrece un mecanismo neutral al lenguaje que sirve
para definir interfaces de objetos distribuidos con estándares que existen para asignar IDL a
Java, así como para asignar Java a IDL. Por último, los objetos CORBA tienen la
posibilidad de pasarse por referencia o valor. El estándar abierto principal, que es el
protocolo basado en TCP/IP para la comunicación a través de CORBA, es el General InterORB (GIOP), que funciona sobre el Protocolo Inter-ORB de Internet (IIOP).
6HUYLFLRVGHFRPXQLFDFLyQHPSUHVDULDO
Aparte de los paradigmas de comunicación distribuida subyacentes, muchos servicios están
construidos sobre estos modelos de comunicación para hacer que las comunicaciones
distribuidas de empresa sean más útiles a las aplicaciones empresariales. Los servicios de
nombres proporcionan una forma de asignación entre referencias a objetos distribuidos y
nombres de objetos legibles. Los sistemas empresariales también emplean a menudo servicios
de directorio y comerciales para localizar y descubrir objetos distribuidos en una red que utiliza
atributos descriptivos e información de tipos acerca de esos objetos. Los mensajes asíncronos
que se envían entre productores y consumidores a menudo se engloban en una de las muchas
opciones de servicios de mensajería que están disponibles para el desarrollador de sistemas
empresariales Java. Tales servicios son comunes a muchas aplicaciones empresariales
distribuidas basadas en comunicaciones y también son componentes fundamentales de una
solución empresarial Java integrada.
Existe un soporte estándar basado en Java para cuatro API’s de servicios empresariales de
comunicación clave:
• Java Naming and Directory Interface (JNDI): un servicio de nombres es el mecanismo
principal que se utiliza en los sistemas distribuidos para hacer referencia a objetos desde las
aplicaciones a través de un nombre que identifica a ese objeto. Los servicios de directorio
ofrecen una forma de buscar objetos en distintos contextos de nombres dada una serie de
atributos de objeto. JNDI ofrece un medio principal para engancharse a los sistemas de
nombres y directorio a partir de aplicaciones empresariales Java. JNDI define una API
estándar para interactuar con tales servicios, y permite que distintos tipos y proveedores se
conecten a la estructura a través de una interfaz de proveedor de servicios.
3
•
•
•
Jini: los servicios comerciales proporcionan una estructura para que los objetos se
identifiquen a sí mismos en un sistema distribuido, utilidades para buscar y descubrir otros
servicios y servicios de objetos remotos. La tecnología Jini es, es esencia, un servicio
comercial en el que se registra, con un servicio de búsqueda, información descriptiva acerca
de procesos o dispositivos remotos. Los clientes Jini pueden buscar tales servicios
utilizando una descripción de plantilla y obtener una serie de elementos de servicio de esas
búsquedas. Los objetos proxy devueltos por estas búsquedas pueden representar marcadores
de procesos o dispositivos remotos. Jini también añade un mecanismo para que los servicios
y los clientes Jini descubran dinámicamente servicios de búsqueda Jini utilizados para el
comercio.
Java Message Service (JMS): es una API Java que define el modo en que las aplicaciones
pueden interactuar con los proveedores de servicios asíncronos de mensajería de un modo
estándar. JMS también incluye una interfaz que es implementada por los proveedores de
servicios de mensajería subyacentes para ofrecer servicios JMS a los clientes. JMS ofrece
un modelo de publicación-suscripción de mensajería punto a punto. La mensajería punto a
punto se lleva a cabo con la implementación de una jerarquía de nodos tópicos en los que
los productores publican mensajes y a los que los consumidores se pueden suscribir. JMS
proporciona una arquitectura de mensajería abstracta que es ampliada por el modelo de cola
de punto a punto y el modelo de publicación-suscripción.
JavaMail: los sistemas de mensajería de correo electrónico juegan en la empresa un papel
muy importante y específico de la aplicación. JavaMail ofrece una forma de interactuar con
un sistema de mensajería de correo electrónico. Con JavaMail, las aplicaciones
empresariales pueden enviar y recibir mensajes de correo a través de Internet. Por tanto,
JavaMail proporciona una API para hacer de interfaz con almacenes de mensajes remotos
utilizados para recibir mensajes de correo y para interactuar con transportes de mensajes
remotos utilizados para enviar mensajes de correo electrónico.
&RPSRQHQWHVHPSUHVDULDOHVEDVDGRVHQFRQWHQHGRUHV
El modelo de componente/contenedor J2EE de desarrollo de aplicaciones empresariales
modernas implica el uso de un entorno de contenedor de terceras partes en el que puedan operar
los componentes empresariales. Los contenedores ofrecen distintas API’s de servicios e
implementaciones, así como entornos de aplicación autónomos. Sin embargo, los entornos de
contenedor también ofrecen servicios de administración y configuración. Los servicios de
administración ofrecen implementaciones de infraestructura para administrar el ciclo de vida, la
manipulación de hilos, la manipulación de las comunicaciones, el volcado de recursos y la
provisión de seguridad en los sistemas para los componentes que operen dentro de sus límites.
Los contenedores J2EE también proporcionan una forma estándar para configurar el estado y
los parámetros de servicio para los componentes que utilicen descriptores de despliegue
estándar basados en XML. En la especificación J2EE se definen dos clases principales de
componentes empresariales del lado del servidor y sus contenedores, los cuales describiremos
aquí:
• Componentes web: los componentes web se definen por medio de VHUYOHWV Java o páginas
JavaServer (JSP). Los componentes web representan la manipulación específica de la
aplicación de solicitudes recibidas por un servidor web y generan respuestas web. Desde el
punto de vista de la administración de contenedores, los VHUYOHWV Java y las JSP reciben un
tratamiento casi idéntico. De hecho, aunque los VHUYOHWV Java basados en web son
componentes Java que utilizan peticiones web estándar y API de respuestas, las JSP se
compilan en VHUYOHWV Java. Sin embargo, las JSP pueden definirse de una forma que es más
familiar para los desarrolladores web. Por ejemplo, los datos de plantilla HTML pueden
incrustarse directamente en la JSP.
• Componentes empresariales JavaBeans (EJB): EJB proporciona un modelo para el
desarrollo de componentes de aplicaciones empresariales del lado del servidor que pueden
hacer que la tarea de creación de aplicaciones empresariales portables y distribuidas sean
4
más fácil que la construcción de aplicaciones empresariales autónomas. Los
contenedores/servidores EJB proporcionan servicios distribuidos de comunicaciones,
servicios de activación de datos, servicios distribuidos comunes de comunicaciones,
servicios de activación de seguridad de sistemas para componentes EJB. Además, se
requiere un mínimo esfuerzo por parte del desarrollador para utilizar estos servicios.
Actualmente, se pueden desarrollar cuatro tipos de EJB. Los componentes (EHDQV) de sesión
sin estado que sirven como motores sin estado de entrada/salida que reciben peticiones de
clientes EJB y generan respuestas. Los componentes de sesión con estado mantienen el
estado entre llamadas sucesivas sobre el componente a cargo del mismo cliente EJB. Los
componentes de entidad de persistencia son componentes que encapsulan datos persistentes
y que exigen que el código de acceso a datos lo haya escrito el desarrollador de
componentes (probablemente con JDBC). Los componentes de entidad de persistencia
administrados por contenedores son componentes que encapsulan datos persistentes y que
activan el código de acceso a datos para que lo genere automáticamente el proveedor del
contenedor.
6HJXULGDGHQODFRQHFWLYLGDGHPSUHVDULDOGHEDVHGHGDWRV
Los datos que fluyen entre un cliente de base de datos y un servidor de base de datos tienen una
naturaleza sensible. Estos datos pueden ser confidenciales y sólo pueden ser vistos por
determinados usuarios. Además, una solución de seguridad con conectividad de base de datos
también puede requerir un modo de limitar el acceso del usuario a determinados tipos de datos.
En tales casos, se suele requerir una forma de que los clientes de las bases de datos se
autentiquen a sí mismos con el servidor de base de datos.
Dado que las aplicaciones empresariales Java se conectan a las bases de datos principalmente a
través de JDBC, algunos medios para ofrecer conexiones JDBC seguras tienen que ser
considerados. Cuando se usa JDBC en un entorno de aplicación empresarial autónoma (es decir
J2EE), hay que proporcionar a través de JDBC un mecanismo para autenticarse a sí mismo y
para establecer el acceso a los datos confidenciales. En entornos J2EE EJB basados en
contenedor, los desarrolladores pueden considerar requerimientos similares de seguridad si
están usando JDBC como mecanismo de acceso a bases de datos. Estos desarrolladores de
componentes de entidad de persistencia administrados por contenedor deben considerar el modo
en que el contenedor J2EE va a proporcionar tales servicios.
6HJXULGDGHPSUHVDULDOHQODVFRPXQLFDFLRQHV
Debido a que el uso de paradigmas de comunicaciones es tan común en entornos empresariales
distribuidos, hay que considerar una forma de asegurar este paradigma. Por desgracia, la forma
más elemental de proporcionar seguridad empresarial de las comunicaciones para aplicaciones
basadas en Java está limitada. La consideración principal a la hora de proporcionar seguridad
empresarial en las comunicaciones ha sido de naturaleza sensible del código Java. Debido a ello,
esta forma de limitar el acceso a recursos fiables por código descargado o para llevar a cabo
operaciones de red básicas es casi exclusiva de la seguridad de red basada en TCP/IP y en RMI.
Otras extensiones para la autenticación y la confidencialidad se utilizan a veces para aumentar la
seguridad de estos modelos. Las aplicaciones CORBA basadas en Java pueden aprovechar el
modelo de seguridad CORBA, que es más complejo. Esta sección explora las opciones
elementales para asegurar estos paradigmas distribuidos de comunicaciones empresariales
basados en Java.
6HJXULGDGEiVLFDHQODVUHGHV
Proporcionar una seguridad básica en la red con Java gira en torno al uso del modelo de control
de seguridad-acceso basado en permisos de Java 2. Los permisos de red tienen nombres que
hacen referencia a un recurso de red en el que el permiso puede ser concedido o denegado. Los
permisos de VRFNHW de red también tienen una serie de acciones que abarcan la serie de
operaciones de VRFNHW que se pueden llevar a cabo.
5
Tres subclases MDYDVHFXULW\3HUPLVVLRQ nos sirven para definir la serie principal de permisos de
seguridad de Java 2, que se pueden usar para proporcionar un control de acceso seguro para la
seguridad de la red. Estas clases de permisos relacionadas con las redes son las clases
MDYDQHW6RFNHW3HUPLVVLRQ, MDYDQHW1HW3HUPLVVLRQ y MDYDODQJ5XQWLPH. Aunque los permisos
para acceder a recursos de red a partir de una JVM están encapsulados por los permisos de
jerarquía de la API Java, la administración de tales permisos de un modo configurable la
encapsula la infraestructura de normas de seguridad de Java 2. El control de acceso en Java 2
está
administrado
por
las
clases
MDYDVHFXULW\$FFHVV&RQWUROOHU
y
MDYDVHFXULW\$FFHVV&RQWURO&RQWH[W
La clase 6RFNHW3HUPLVVLRQ encapsula permisos de un VRFNHW de red. Un SocketPermission se
construye con un nombre de KRVWy una serie de acciones, como se ilustra en la tabla 1.1.
7DEOD
Tipos de permisos de un VRFNHW
1RPEUH\DFFLyQGHOSHUPLVRGHVRFNHW
'HVFULSFLyQ
SocketPermission sp=new
SocketPermission(“www.prueba.com”, “accept”);
SocketPermission sp=new
SocketPermission(“205.127.44.44”, “accept,
connect”);
SocketPermission sp=new SocketPermission(“*.com”,
“accept, connect”);
Da permiso para aceptar conexiones de
un solo nombre de dominio.
Da permiso para aceptar conexiones y
conectarse con una determinada
dirección IP
Da permiso para aceptar/conectar en
cualquier nombre de dominio que
termine con .com.
Da permiso para aceptar/conectar en el
puerto 80 del dominio prueba.com.
SocketPermission sp=new
SocketPermission(“*.prueba.com:80”, “accept,
connect”);
SocketPermission sp=new
SocketPermission(“*.prueba.com:1024-”, “accept,
connect”);
SocketPermission sp=new
SocketPermission(“*.prueba.com:-1013”, “accept,
connect”);
SocketPermission sp=new
SocketPermission(“www.prueba.com:4000:4020”,
“accept, connect”);
SocketPermission sp=new SocketPermission(“*”,
“accept, connect”);
SocketPermission sp=new SocketPermission(“”,
“accept, listen, connect”);
SocketPermission sp=new
SocketPermission(“localhost”, “accept, connect”);
Acepta/conecta en los puertos no
reservados.
Acepta/conecta
reservados.
en
los
puertos
Acepta/conecta en los puertos 4000 a
4020.
Acepta/conecta en todas las máquinas
en todos los puertos.
Acepta/conecta/escucha
sólo
en
localhost.
Acepta/conecta/escucha
sólo
en
localhost.
El nombre del KRVW de destino y las acciones que se especifican en un archivo de normas de
seguridad Java 2 adopta la forma:
grant
{
permission java.io.SocketPermission “localhost”, “accept, listen, connect”;
permission java.net.SocketPermission www.prueba.com”, “accept”;
};
Los permisos para redes que se definen a través de la clase NetPermission sólo tienen un
nombre de destino sin acciones definidas. Un NetPermission se construye con uno de los
nombres de destino, como se ilustra en la Tabla 1.2.
6
Tipos de permisos para redes
7DEOD
1RPEUHGHOSHUPLVRSDUDUHGHV
'HVFULSFLyQ
NetPermission np=new
NetPermission(“requestPasswordAuthentication”);
Da permiso para obtener una
constraseña
de
la
java.net.PasswordAuthentication
registrada.
Da permiso para registrar el
java.net.Authenticator utilizado para
obtener información de autenticación.
Da permiso para designar un
manipulador de flujos al crear una
URL.
NetPermission np=new
NetPermission(“setDefaultAuthenticator”);
NetPermission np=new
NetPermission(“specifyStreamHandler”);
Como
observará
que
el
uso
de
las
clases
java.net.Authenticator
y
java.net.PasswordAuthentication se ve afectado por las dos primeras filas de la Tabla 1.2. La
clase java.net.Authenticator proporciona formas de obtener información sobre la autenticación
desde una conexión de red. Las subclases se registran con el proceso JVM a cargo de una
aplicación
Java
a
través
de
una
llamada
al
método
estático
Authenticator.setDefault(Authenticator). Si se concede el permiso “setDefaultAuthenticator”, la
llamada a este método será permitida; caso contrario, se presentará una SecurityException. El
método getPasswordAuthentication() se invoca en la subclase Authenticator durante la
autenticación basada en constraseña. Se puede utilizar un objeto PasswordAuthentication para
devolver una cadena de nombre de usuario y una matriz char[] de constraseña.
Se puede hacer una llamada estática Authenticator.requestPasswordAuthentication() se el
proceso JVM establece el permiso “requestPasswordAuthentication”. El método
requestPasswordAuthentication() pide un objeto PasswordAuthentication al autenticador que se
ha registrado en el sistema. Se proporciona un objeto InetAddress que especifica la dirección de
petición de usuario y una cadena de esquema de protocolo como entrada al método
requestPasswordAuthentication().
Por último, aparte de los tipos SocketPermission y NetPermission, se puede usar un nombre de
destino “setFactory” afiliado a RuntimePermission con el fin de permitir que una aplicación
establezca una factoría de VRFNHWV distinta a través de las clases java.net.Socket y
java.net.ServerSocket. La posibilidad de establecer un manipulador de flujos URL a través de la
clase java.net.URL también se ve afectada por este permiso.
Todos estos mecanismos de seguridad básicos en las redes Java solamente permiten la provisión
de un control de acceso básico para operaciones fiables de redes. No se ofrecen explícitamente
formas de autenticar clientes y servidores de red o de proveer sesiones confidenciales. Para tales
servicios, es posible utilizar las API Java Authentication and Authorization Service (JAAS), y
Java Secure Socket Extension (JSSE) que se empaquetan por separado.
6HJXULGDG50,
Las formas predeterminadas de proporcionar seguridad a las aplicaciones basadas en RMI es
java.rmi.RMISecurityManager. Se puede usar para definir parámetros de seguridad que dirigen
la descarga de código en virtud de las características propias de RMI para la descarga de código
dinámico. Cuando no se establece un administrador de seguridad en una aplicación basada en
RMI, no se descargará código RMI desde ubicaciones remotas. Durante el inicio de una
aplicación basada en RMI, normalmente se establece el uso de RMISecurityManager a través de
una llamada, de esta forma:
Java.lang.System.setSecurityManager(new java.rmi.RMISecurityManager());
7
La forma estándar en virtud de la cual se establecen normas de seguridad Java 2 en ciertas
ubicaciones de bases de código pueden utilizarse para controlar los niveles de permiso en
aplicaciones basadas en RMI.
Tales mecanismos sólo conceden o deniegan el acceso a determinados recursos JVM para
código RMI descargado de una ubicación remota. Los temas amplios de proporcionar
autenticación y confidencialidad en sesiones de cliente/servidor RMI no entran en el modelo
actual de RMI. El JAAS se puede usar en conjunción con RMI y con el modelo de seguridad de
Java 2 para limitar el acceso basado en un determinado tema, aparte de la ubicación de la base
de código descargada. Las extensiones de VRFNHWV SSL también se pueden utilizar para ofrecer
una forma de asegurar la sesión de comunicaciones por la que viaja el tráfico RMI.
Existe una nueva especificación para mejorar las opciones de seguridad de RMI. Esta
especificación destaca los medios (formas) para autenticar sujetos cliente y servidor implicados
en invocaciones de métodos remotos, medios para delegar al sujeto cliente tal que se puedan
ejecutar invocaciones al servidor remoto en nombre del sujeto, y medios para dotar a los datos
de integridad y confidencialidad al invocar a los métodos remotos. Estas mejoras cuentan con
un paquete nuevo java.rmi.constraint, que contiene clases que permiten a los clientes y
servidores imponer restricciones de seguridad sobre las invocaciones de métodos remotos. Las
restricciones para especificar la integridad y confidencialidad de los datos enviados a través de
invocaciones de métodos remotos vienen encapsuladas por las clases de este paquete. Las
restricciones a la autenticación y asociación de identidades de cliente y servidor con las
llamadas de métodos remotos también vienen encapsuladas por las clases de este paquete.
6HJXULGDGHQ&25%$
Las aplicaciones basadas en CORBA también requieren una forma de asegurar el paradigma de
objeto distribuido CORBA. El Servicio de Seguridad de CORBA es un componente OMG
CORBAService que hace referencia a la seguridad de objetos distribuidos en aplicaciones
basadas en CORBA. Este servicio se define para que funcione principalmente sobre la capa
ORB, pero también define algunos cambios en dicha capa. Al usar componentes que
implementan la Especificación del Servicio de Seguridad, las aplicaciones empresariales
basadas en CORBA obtienen la ventaja de la protección de seguridad basada en estándares,
entre las se incluyen la protección de identidad, la autenticidad, la no repudiación, la
autorización, la auditoría, la integridad y la confidencialidad.
6HJXULGDGGHVHUYLFLRVHPSUHVDULDOHVGHFRPXQLFDFLRQHV
Por encima de la seguridad básica en las comunicaciones distribuidas, estos servicios comunes
que se construyen sobre tales paradigmas distribuidos también podrían requerir un cierto grado
de seguridad aumentada. Dado que tales servicios se suelen manifestar como servidores
distribuidos, los primeros mecanismos necesarios para una utilización segura son: que los
clientes se autentiquen a sí mismos con estos servidores. La confidencialidad de las sesiones con
tales servicios suele proporcionarla el proveedor de servicios a nivel de la capa de transporte. En
esta sección, exploraremos brevemente estos servicios de seguridad que se exponen a través de
mecanismos Java estándar en servicios de comunicaciones distribuidas, como los servicios de
nombres, de directorios, de comercio y de mensajería. Por lo tanto, exploraremos brevemente
los mecanismos de seguridad estándar que proporcionan JNDI, Jini, JMS y JavaMail.
6HJXULGDGHQ-1',
Para poder utilizar los servicios de un servicio de nombres o directorios, los usuarios de la API
cliente JNDI crean primero una referencia a un contexto inicial del servicio de nombres o
directorios que interese. Este proceso inicial de contexto/creación establece una conexión con el
servicio cuando se construye con una serie de propiedades que describen qué biblioteca
específica de proveedor de servicio de nombres o directorios usar, la URL del proceso de
servicio de nombres o directorios, y quizá un nombre de usuario y unas credenciales de usuario.
8
También se pueden establecer otras propiedades, cuyos nombres se definen como atributos
públicos estáticos en la interfaz javax.naming.Context. Una clase javax.naming.InitialContext
que implementa la interfaz Context se puede usar para crear un puntero a un servicio de
nombres concreto. Al pasar un objeto Properties establecido como elementos que utilizan los
nombres de claves java.naming.XXX que se definen en la interfaz Context al constructor de
InitialContext, se establecerán todas las propiedades públicas estáticas Context.XXX que sean
necesarias, que se usarán durante la inicialización de InitialContext. En la tabla 1.3 se definen
unas cuantas propiedades públicas estáticas relacionandas con la seguridad.
7DEOD
Propiedades de contexto
3URSLHGDGGHFRQWH[WR
'HVFULSFLyQ
INITIAL_CONTEXT_FACTORY
Paquete completamente cualificado y nombre de clase del
proveedor utilizada para crear un contexto JNDI.
PROVIDER_URL
URL que especifica el protocolo, host y puerto sobre el
que se está ejecutando el servicio de nombres o
directorios. Es decir: <protocolo>://<host>:<puerto>.
SECURITY_PRINCIPAL
Nombre del principal (por ejemplo, nombre de usuario)
que tiene que ser comprobado por el servicio de nombres
o directorios en caso de que se requiera autenticación.
SECURITY_CREDENTIALS
Credenciales del principal (por ejemplo, una contraseña)
que tiene que ser comprobada por el servicio de nombres
o directorios en caso de que requiera autenticación.
SECURITY_PROTOCOL
Especifica el protocolo de seguridad a utilizar (por
ejemplo, SSL).
SECURITY_AUTHENTICATION Especifica el nivel de seguridad que se va a usar, como
none, simple o strong.
AUTHORITATIVE
El valor true indica que el acceso al servicio es para la
fuente más autorizada.
De todas las propiedades que se definen en la Tabla 1.3, las dos primeras
(INITIAL_CONTEXT_FACTORY y PROVIDER_URL) probablemente sean las más
utilizadas en los programas JNDI. Las propiedades SECURITY_PRINCIPAL y
SECURITY_CREDENTIALS suelen emplearse con mucha frecuencia para la autenticación
básica. Si una propiedad queda sin definirse, se suele utilizar un valor predeterminado, lo que es
válido en la mayoría de los casos. La creación de un InitialContext es, por tanto, directa como se
ve en este ejemplo:
Properties propiedades=new Properties();
propiedades.setProperty(Context.INITIAL_CONTEXT_FACTORY,”com.unsj.MiJNDIFactory
”);
propiedades.setProperty(Context.PROVIDER_URL,”protocol://123.205.155:5000”);
propiedades.setProperty(Context.SECURITY_PRINCIPAL,”administrador”);
propiedades.setProperty(Context.SECURITY_CREDENCIALS,”yamiout”);
propiedades.setProperty(Context.SECURITY_PROTOCOL,”SSL”);
propiedades.setProperty(Context.SECURITY_AUTHENTICATION,”strong”);
Context contexto=new InitialContext(propiedades);
Object miObjetoDistribuido=context.lookup(“NombreDeMiObjeto”);
6HJXULGDGHQ-LQL
El entorno dinámico para redes de Jini puede suponer que haya una cantidad importante de
código móvil que se intercambie entre procesos distribuidos. Por consiguiente, el acceso a los
recursos y permisos de este código descargado deberá se controlado de algún modo.
Desafortunadamente, el alcance de las consideraciones de seguridad que utiliza el modelo
dinámico para redes de Jini está muy limitado. La seguridad en Jini se deriva del modelo de
9
seguridad básico de Java 2 y del uso de un administrador de seguridad RMI. De hecho, durante
el proceso de descubriemiento Jini, el conjunto de grupos que pueden ser unidos por un servicio
Jini o un cliente Jini puede limitarse a través de mecanismos de seguridad de Java 2.
La clase net.jini.discovery.DiscoveryPermission encapsula un tipo de permiso Java 2 que limita
el acceso a los recursos de determinados grupos de redes Jini. Cuando un cliente Jini, servicio
Jini o servicio de búsqueda Jini trata de descubrir otros servicios de búsqueda en la red, invoca
al constructor net.jini.discovery.LookupDiscovery con una lista de nombres de grupo del tipo
String. Estas redes Jini que pertenecen a uno de los grupos especificados pueden ser
descubiertas a través de este proceso. Si el usuario LookupDiscovery (cliente Jini, servicio Jini
o servicio de búsqueda Jini) no tiene permiso para acceder a un determinado grupo, el proceso
de descubrimiento de servicios de búsqueda Jini de ese grupo terminará por provocar una
excepción de seguridad.
La clase DiscoveryPermission y la representación asociada de su archivo de normas puede estar
relacionada con un nombre de grupo de descubrimiento de destino. Este nombre de grupo puede
ser definido en función de las formas siguientes:
• “name”: un nombre de destino especificado identifica un determinado grupo de red Jini.
• “public” o “”: la cadena “public” o una cadena vacía se pueden usar para designar un grupo
público al que todas las aplicaciones pueden acceder.
• “*”: identifica a todos los grupos.
• “*.unj.edu.ar”: se puede usar un prefijo “*” para crear comodines de grupos en un
determinado dominio de grupos.
Por lo tanto, se puede especificar un DiscoveryPermission en un archivo de normas Java 2
estándar, como se ejemplifica aquí:
grant SignedBy “UNSJ” CodBase “http://www.unsj.edu.ar/-“
{
permission net.jini.discovery.DiscoveryPermission “alumnos”;
};
En el ejemplo anterior, el código cargado por la aplicación Jini afectado por este archivo de
normas concede permisos de descubrimiento a un grupo de destino denominado “alumnos” al
código cargado en “http://www.unsj.edu.ar” y firmado por “UNSJ”.
Por lo tanto, los procesos JVM de cliente Jini, de servicio Jini o de servicio de búsqueda Jini
deberán estar asociados a unas normas de seguridad Java 2 durante el inicio. Además, las
aplicaciones Jini deberán establecer un administrador de seguridad durante la inicialización
utilizando un administrador de seguridad RMI, como RMISecurityManager que describimos
anteriormente.
Aunque tales controles indican qué grupos de búsqueda pueden ser descubiertos por sus
aplicaciones, podría preguntarse: ¿cómo la infraestructura Jini puede autenticar tales grupos? Es
decir, si configura su aplicación para que permita el descrubimiento de servicios de búsqueda
pertenecientes al grupo “xyz”, ¿qué mecanismos garantizan que el servicio de búsqueda
pertenece verdaderamente a un grupo? La respuesta más sencilla es que actualmente no se
ofrecen las suficientes garantías. La firma de código y la especificación de la ubicación de la
base de código son las únicas opciones reales que proporcionan algún nivel de garantía en la
identidad del código. Anticipamos que Jini será ampliado en el futuro con mecanismos de
seguridad más rigurosos. En concreto, el modelo de seguridad Jini, se capitalizará en el nuevo
modelo de seguridad RMI que se está desarrollando.
10
6HJXULGDG-06
La seguridad en los sistemas de mensajería dependerá mucho del fabricante de PLGGOHZDUH. No
obstante, JMS proporciona varias formas para permitir la autenticación sencilla de cliente
basada en contraseña con el servidor de mensajes PLGGOHZDUH. JMS lleva a cabo esto
permitiendo a los clientes JMS que faciliten al servidor de mensajes un nombre de usuario y una
contraseña cuando se crea la conexión inicial con el servidor.
Se puede usar un clase javax.jmsQueueConnectionFactory para crear un objeto inicial
javax.jms.QueueConnection. QueueConnection representa la conexión de cliente con el servidor
de cola de mensajes punto a punto de PLGGOHZDUH JMS. El método estático
QueueConnectionFactory.createQueueConnection() puede tomar parámetros tipo String con el
nombre del usuario y la contraseña que se utilizan para autenticar al cliente JMS frente al
servidor middleware. Si la autenticación del cliente falla, se presentará una
javax.jms.JMSSecurityException.
El proceso es parecido en la mensajería de publicación-suscripción. Se puede usar una clase
javax.jms.TopicConnectionFactory para crear un objeto inicial javax.jms.TopicConnection que
representa la conexión de cliente con el servidor de temas de mensajes de publicaciónsuscripción de PLGGOHZDUH JMS.
El método estático TopicConnectionFactory.createTopicConnection() puede entonces tomar las
cadenas con el nombre de usuario y la contraseña como parámetros con el fin de autenticar el
cliente JMS con el servidor de PLGGOHZDUH. Si falla la autenticación del cliente, se presenta una
javax.jms.JMSSecurityException.
6HJXULGDGHQ-DYD0DLO
La API JavaMail también expone una forma de permitir a los clientes autenticarse con un
servidor de mensajería remoto. En este caso, el servidor de mensajería es un servidor de correo
electrónico. Antes de que un cliente JavaMail pueda interactuar con un sistema de mensajería de
correo electrónico, deberá establecer una sesión de correo con un servidor de correo. Se pueden
usar dos métodos en la clase Session para obtener una instancia Session. El método
getDefaultInstance() se utiliza para devolver una instancia de una sesión de correo que puede ser
compartida por otras aplicaciones que se ejecuten en la misma plataforma. El método
getInstance() se puede usar para crear una sesión de correo que sea única y que no esté
compartida con otras aplicaciones. Ambos métodos toman un objeto javax.util.Properties como
argumento que puede tener valores establecidos con elementos estándar de propiedad.
La creación de un objeto Session también implica el uso de un parámetro
javax.mail.Authenticator con tales métodos estáticos. La clase abstracta Authenticator está
subclasificada por proveedores de servicios que implementan objetos que saben cómo autenticar
un usuario con un servidor de correo. Si se emplea un Authenticator nulo para crear un objeto
Session utilizando un método estático Session.getDefaultInstance() y la instancia
predeterminada ya ha sido creada, el objeto Authenticator deberá coincidir con la instancia que
se utilizó para crear la sesión original.
El Authenticator lo usa principalmente el entorno de servicios de mensajería de correo como
retrollamada para requerir información de autenticación del usuario. La clase
javax.mail.PasswordAuthentication se usa para encapsular un nombre de usuario y una
contraseña,
que
puede
establecerse
en
el
objeto
Session
utilizando
setPasswordAuthentication(URLName, PasswordAuthentication) para su uso posterior en la
sesión o a cargo de otras aplicaciones. El URLName encapsula los elementos de datos de un
URL que, en este caso, se usa para asociar un URL de servidor de correo con la información de
autenticación de la contraseña. Sin embargo, el Authenticator, la clase PasswordAuthentication
11
y los métodos asociados del objeto Session son utilizados por un proveedor de almacenamiento
de mensajes o de transporte de correo.
La forma principal en virtud de la cual el cliente de la aplicación JavaMail proporciona
información sobre autenticación al sistema de correo se produce a través de un objeto
javax.mail.Store o javax.mail.Transport. Tales objetos se obtienen del objeto Session. El objeto
Store encapsula un puntero a un almacén de mensajes de correo electrónico (servidor POP o
servidor IMAP) para recuperar mensajes de correo electrónico. El objeto Transport encapsula
un marcador a un mecanismo de transporte de correo electrónico (servidor SMTP) que sirve
para enviar mensajes de correo electrónico. Las clases Store y Transport se heredan ambas de la
clase javax.mail.Service. La clase Service define una colección de métodos connect() que
permiten al usuario JavaMail conectarse con el servicio de correo electrónico concreto (almacén
de mensajes de correo de usuario o servicio de transporte). Dos de los métodos connect()
aceptan un nombre de usuario y una contraseña para la autenticación de un usuario con el
servidor de correo remoto. Utilizando tales métodos, un cliente de la API JavaMail puede
autenticarse a sí mismo con un servidor SMTP, POP o IMAP al conectarse con tales servidores.
6HJXULGDGGHFRPSRQHQWHVHPSUHVDULDOHVEDVDGRVHQFRQWHQHGRUHV
Los componentes basados en J2EE, como los servlets Java, JSP y EJB, emplean mecanismos de
seguridad de alto nivel construidos sobre el modelo de seguridad básico de Java 2. Estos
mecanismos liberan a la Web y al desarrollador de componentes EJB de la necesidad de saber
mucho sobre el modelo de seguridad subyacente de Java 2. En vez de ello, los desarrolladores se
centran en especificar las funciones de seguridad y las funciones asociadas con los privilegios
de acceso a componentes. Esta sección describe las disposiciones básicas de seguridad de la
seguridad de componentes web y EJB.
6HJXULGDGHQORVFRPSRQHQWHV:HE
Las estructuras Java Servlet y JSP están integradas con muchas opciones de seguridad de Java
2.0 y también aumentan la estructura de seguridad de Java 2.0 con el fin de dar seguridad a los
componentes web. La seguridad de Java Servlet y JSP (componente Web de Java) trata sobre la
identidad y autenticación , la autorización, la integridad y la confidencialidad. En concreto, la
estructura de componentes web J2EE ofrece un forma de definir declarativamente atributos de
seguridad de un descriptor de despliegue XML de una aplicación web estándar que se usa para
configurar los aspectos operativos de seguridad en línea de los componentes web.
Alternativamente, ciertas prestaciones de la estructura de seguridad también se exponen a los
componentes web a través de API que permiten la provisión de una seguridad programática más
elaborada a cargo de desarrolladores de aplicaciones de componentes web.
Un elemento de datos XML, que se define en el elemento raíz del descriptor de despliegue
XML de una aplicación web estándar, se usa para definir la configuración de la autenticación
concreta que utiliza una aplicación web. El tipo de autenticación que se puede usar puede
especificarse de una de cuatro formas, entre las que se incluye la autenticación de contraseña
básica, la autenticación basada en funciones resúmen de mensajes, la autenticación basada en
formularios HTML y la autenticación basada en certificados de cliente SSL. Durante el tiempo
de ejecución, cierta información relacionada con la autenticación y asociada con una petición
HTTP también puede ser extraída en el lado del servidor por el servlet o JSP.
Cuando una petición es enviada a un servidor web con un protocolo seguro, se puede usar un
método del lado del servidor para devolver un valor booleano que indique este hecho. Cuando
se utiliza SSL con HTTP, también se puede devolver una serie de objetos de certificado X509
desde una llamada al objeto requerido.
Una vez que se ha identificado a un usuario con un mecanismo de autenticación concreto, puede
determinarse la autorización para acceder a los recursos de componentes web identificados por
12
URL. La autorización de componentes web se basa en una técnica de control de acceso basada
en funciones. Las funciones de seguridad se asignan a principales o grupos. Cuando un principal
concreto realiza una petición sobre un recurso con una función de seguridad asociada, el nombre
del principal o grupo que esté asociado con la función requerida, se pasa, con el fin de
determinar si se permite o no el acceso al recurso. Se puede definir un conjunto de funciones de
seguridad válidas para un entorno concreto de componentes web J2EE en el descriptor de
despliegue XML de ese componente.
6HJXULGDGHQ(-%
Actualmente, los mecanismos estándar de seguridad que se definen en los EJB se centran
mucho en proporcionar un conjunto mínimo de construcciones para el control de acceso a la
seguridad de EJB. Aunque un mecanismo para la autenticación de un usuario está implícito por
el hecho de que a un determinado usuario se le debe conceder el acceso a un determinado
método EJB, en EJB v1.1 y en J2EE v1.2 no se definen formas estándar de autenticar a un
usuario. No obstante, tales mecanismos estándar están previstos para J2EE v1.3, y con toda
probabilidad se centrarán en el uso del JAAS. Además, también se necesita una combinación de
mecanismos de seguridad específicos del contenedor y definibles por el usuario para crear un
entorno verdaderamente seguro y un entorno de seguridad práctico para los EJB.
Aunque la especificación EJB no recomienda una lógica de control de acceso a la seguridad
implementado por componentes, en muchos casos prácticos esto es inevitable. Siempre que se
realice una llamada a un método de comprobación de funciones de seguridad EJB desde el
código EJB, se deberán definir referencias de función asociadas en un descriptor de despliegue
XML para el EJB. Tales referencias de función y otros mecanismos de especificación de
funciones pueden ser utilizadas para definir declarativamente qué funciones de seguridad de los
clientes EJB pueden invocar a métodos EJB concretos.
5HVXPHQ
Cada vez más se utilizan tecnologías empresariales Java y J2EE en sistemas empresariales con
el fin de permitir el acceso a los datos empresariales, a la conectividad de las comunicaciones a
la Web y a la construcción de aplicaciones escalables de forma rápida. Java complementa tales
tecnologías con unos cuantos mecanismos estándar de seguridad empresarial distribuida. Como
hemos podido ver este trabajo, el alcance de tales mecanismos puede ser mínimo o muy amplio,
dependiendo de la tecnología de que trate.
Aunque a Java todavía le queda mucho camino por recorrer para proporcionar un entorno
estándar seguro para algunas tecnologías empresariales Java, existe una infraestructura
suficiente para que los desarrolladores de aplicaciones empiecen a implementar aplicaciones
empresariales seguras distribuidas en algunos casos. En este trabajo hemos explorado los
distintos mecanismos que tienen a su disposición los desarrolladores de aplicaciones en este
sentido.
%LEOLRJUDItD
Seguridad en Java – Edición Especial – Prentice Hall – J. Jaworski – P. J. Perrone.
Client/Server programming with Java and Corba 2nd. Ed.- J. Wiley – R. Orfali – D. Harkeyl.
Java 2 – Manual de usuario y Tutorial 2da Edición – Alfaomega Ra-Ma – Agustín Froufe.
La Biblia del Java – Anaya – L. Vanhelsuwé.
Aplicaciones de negocios en Java – Compumagazine – J. Bourdette.
El lenguaje de programación Java – Addison Wesley – K. Arnold – J. Golsing.
Java: biblioteca del programador – McGraw-Hill – S. Sam Lalani – K. Jamsa.
Como programar en Java – Prentice-Hall – H. M. Deitel – P.J. Deitel.
13