78
SEGURIDAD JAVAEE Seguridad

Seguridad JavaEE

Embed Size (px)

Citation preview

SEGURIDAD JAVAEE

Seguridad

INTRODUCCIÓN

Las aplicaciones JavaEE constan de componentes que pueden utilizar tanto recursos protegidos, como recursos no protegidos.

A menudo, es necesario proteger algunos recursos para asegurar que sólo usuarios autenticados tienen acceso a dichos recursos. La Autorización es el proceso que permite establecer un acceso controlado a dichos recursos.

El proceso de Autorización se basa en la identificación y en la autenticación. La identificación es el proceso que nos permite reconocer una entidad en nuestro sistema y la autenticación es el proceso que verifica la identidad de dicha entidad (entendiendo como entidad un usuario, dispositivo, proceso, etc).

La Autorización y la Autenticación son procesos que no se requieren para una entidad que accede a recursos no protegidos, lo que se conoce comúnmente como acceso anónimo

INTRODUCCIÓN

INTRODUCCIÓN

Usuario autorizado

INTRODUCCIÓN

CARACTERÍSTICAS DE LA SEGURIDAD DE

APLICACIÓN

Autenticación: El medio por el cuál las entidades que intervienen en un escenario de comunicación (por ejemplo, cliente-servidor) se demuestran la una a la otra que están actuando en nombre de identidades específicas que están autorizadas para el acceso. Esto asegura que los usuarios son quién dicen ser.

Autorización o Control de Acceso: El medio por el cuál las interacciones con los recursos se limitan a un grupo de usuarios o programas, con el fin de hacer cumplir la integridad, confidencialidad, o las restricciones de disponibilidad. Esto asegura que los usuarios tienen acceso para ejecutar operaciones o acceso a datos.

CARACTERÍSTICAS DE LA SEGURIDAD DE

APLICACIÓN

Integridad de los datos: El medio usado para demostrar que la información no ha sido modificada por un tercero. Por ejemplo, un receptor de los datos enviados sobre una red abierta debe ser capaz de detectar y rechazar los mensajes que hubieran sido modificados después de haber sido enviados. Esto asegura que sólo usuarios autorizados pueden modificar datos.

Confidencialidad o Privacidad de Datos: El medio usado para asegurar que la información se hace disponible sólo para los usuarios que están autorizados para acceder a ella. Esto asegura que sólo usuarios autorizados pueden consultar datos sensibles.

CARACTERÍSTICAS DE LA SEGURIDAD DE

APLICACIÓN

Non-repudiation: El medio usado para demostrar que un usuario llevó a cabo alguna acción. Esto asegura que pueda ser demostrado que determinadas transacciones han ocurrido.

Quality of Service (Qos): El medio usado para proporcionar mejores servicios al tráfico de red sobre varias tecnologías.

Auditoría: El medio usado para obtener un registro de eventos relacionados con la seguridad con el fin de evaluar la efectividad de los mecanismos y políticas de seguridad. Para permitir esto, el sistema mantiene un registro de información de transacciones y seguridad.

TRABAJANDO CON REINOS, USUARIOS, GRUPOS

Y ROLES

DEF. Reino: Para una aplicación Web, un reino es una base de datos de usuarios y grupos que identifica los usuarios válidos para la aplicación Web y que son controlados por la misma política de autenticación.

DEF. Usuario: Un usuario es un individuo (o un programa) identificado que ha sido definido en el Servidor de Aplicaciones. En una aplicación Web, un usuario puede tener un conjunto de roles asociados con esa identidad que le dan derechos de acceso a todos los recursos protegidos por esos roles. Los usuarios pueden ser asociados con un grupo.

TRABAJANDO CON REINOS, USUARIOS, GRUPOS

Y ROLES

DEF. Grupo: Un grupo es un conjunto de usuarios autenticados, clasificados por rasgos comunes, definido en un Servidor de Aplicaciones. Por ejemplo, muchos de los clientes de una aplicación de e-commerce pueden pertenecer al grupo de CLIENTES, mientras que los clientes preferentes (los que más compran) pertenecerían al grupo de PREFERENTES. Categorizar usuarios en grupos hace más fácil el control de acceso cuando el sistema cuenta con un gran número de usuarios.

Un grupo en el servidor de aplicaciones tiene un alcance distinto que el de un rol. Un grupo del AS tiene un alcance que contempla a todo el AS, mientras que un rol se asocia sólo con una aplicación específica en el AS.

DEF. Rol: Un rol es un nombre abstracto que define el permiso para acceder a un conjunto específico de recursos en una aplicación. Un rol puede verse como una llave que puede abrir una cerradura determinada. Muchas personas pueden tener una copia de la llave. A la cerradura no le importa quien seas, sólo que tengas la llave correcta.

TRABAJANDO CON REINOS, USUARIOS, GRUPOS

Y ROLES

DEF. Principal: Un principal es una entidad que puede ser autenticada por un protocolo de autenticación en un servicio de seguridad que está desplegado en una empresa. Un principal se identifica usando un nombre de principal y se autentica usando datos de autenticación (passwords, credenciales, etc).

DEF. Política de Seguridad del Dominio (también conocido como Dominio de Seguridad o reino): Es el alcance sobre el que se define y se impone una política común de seguridad, gestionada por el administrador del servicio de seguridad.

TRABAJANDO CON REINOS, USUARIOS, GRUPOS

Y ROLES

DEF. Atributos de Seguridad: Un conjunto de atributos de seguridad se asocia con todos los principals. Los atributos de seguridad tienen muchos usos, por ejemplo, el acceso a recursos protegidos y auditoria de usuarios. Los atributos de seguridad pueden asociarse con un principal por medio de un protocolo de autenticación.

DEF. Credencial: Un credencial contiene o referencia atributos de seguridad usados para autenticar un principal.

JAAS (JAVA JAVA AUTHENTICATION AND

AUTHORIZATION SERVICE)

JAAS fue introducido como un paquete adicional (extensión) en la J2SDK v 1.3

A partir de la v 1.4 viene integrado con la SDK.

Es por tanto, parte de J2SE, no de la J2EE.

JAAS puede ser usado para dos propósitos:

Para autenticación de usuarios, es decir para determinar quién esta actualmente ejecutando código Java, sin importar si el código esta corriendo como una aplicación, un applet, un bean o un servlet y

Para autorización de usuarios de manera que se asegure que tienen los permisos requeridos para realizar las acciones ejecutadas.

JAAS

INTRODUCCIÓN

JAAS es un modelo de autenticación pluggable. Esto permite a las aplicaciones permanecer independientes de las tecnologías de autenticación subyacentes.

Tecnologías de autenticación nuevas o actualizadas pueden ser insertadas (plugged) bajo una aplicación sin que se requieran modificaciones a la aplicación en si misma.

JAAS

INTRODUCCIÓN

Las aplicaciones permiten el proceso de autenticación instanciando un objeto de tipo LoginContext que hace referencia a un objeto Configuration para determinar la tecnología/s de autenticación o LoginModule(s), que serán usados en el proceso de autenticación.

Las implementaciones de LoginModule típicas suelen solicitar y verificar un nombre de usuario y una password. Otras implementaciones pueden ser por medio de la lectura y verificación de voz, huellas dactilares, etc

JAAS

INTRODUCCIÓN

Una vez que el usuario o servicio que ejecuta el código

ha sido autenticado, el componente JAAS de

autorización se pone en funcionamiento para proteger

el acceso a recursos sensibles.

Las decisiones de control de acceso se basan en el

usuario o servicio que ejecuta el código, que es

representado mediante un objeto de la clase Subject.

El Subject es actualizado por un LoginModule con los

Principals y credenciales si el proceso de autenticación

es exitoso.

JAAS

CORE CLASSES AND INTERFACES

Las clases e interfaces principales de

JAAS se pueden dividir en tres categorías:

Common Classes

Subject, Principal, Credential (actually, any

Object)

Authentication Classes e Interfaces

LoginContext, LoginModule, CallbackHandler,

Callback

Authorization Classes

Policy, AuthPermission,

JAAS

COMMON CLASSES

Las clases comunes son todas aquellas

compartidas por los dos componentes del API

JASS, autenticación y autorización

JAAS

COMMON CLASSES: SUBJECT

Para autorizar el acceso a los recursos, las aplicaciones necesitan primero autenticar el origen de la solicitud.

El framework JAAS define el término subject para representar el origen de la solicitud. Un subject puede ser cualquier entidad, ya sea una persona o un servicio.

Una vez el subject es autenticado un javax.security.auth.Subject es rellenado con las identidades asociadas, o Principals.

Un subject puede tener muchos Principals. Por ejemplo, una persona puede tener un nombre principal (“Roberto Matas”) y un código identificativo principal (“1234-56”), que lo distingue de otros subjects.

JAAS

COMMON CLASSES: SUBJECT

Un Subject puede tener también atributos de seguridad propios, conocidos con el nombre de credentials.

Credenciales sensibles, que requieren una protección especial, como por ejemplo una clave criptográfica privada, se almacenan dentro de un conjunto (Set) de credenciales privados.

Los Credenciales cuya finalidad es ser compartidos, como por ejemplo certificados públicos, se almacenan dentro de conjunto (Set) de credenciales públicos.

Se requieren diferentes tipos de permisos para acceder y modificar los diferentes conjuntos de credenciales.

JAAS

COMMON CLASSES: SUBJECT

Constructores:

public Subject();

public Subject(boolean readOnly, Set principals,

Set pubCredentials, Set privCredentials);

El programador de la aplicación no tiene que

instanciar manualmente un objeto Subject. Si la

aplicación instancia un LoginContext y no le

proporciona ningún Subject al constructor, el

LoginContext instanciará uno vacío

JAAS

COMMON CLASSES: SUBJECT

Método Descripción

public Set getPrincipals();Devuelve todos los Principals contenidos en el

Subject

public Set getPrincipals(Class c);Devuelve todos los Principals contenidos en el

Subject que sean una instancia de la Clase c,o una instancia de una subclase de c

public Set getPublicCredentials();Devuelve todos los credenciales públicos

contenidos en el Subject

public Set getPublicCredentials(Class c);

Devuelve todos los credenciales públicoscontenidos en el Subject que sean unainstancia de la Clase c, o una instancia deuna subclase de c

public Set getPrivateCredentials();Devuelve todos los credenciales privados

contenidos en el Subject

public Set getPrivateCredentials(Class c);

Devuelve todos los credenciales privadoscontenidos en el Subject que sean unainstancia de la Clase c, o una instancia deuna subclase de c

public boolean isReadOnly(); Consulta si el Subject es de sólo lectura

JAAS

COMMON CLASSES: PRINCIPAL

Como hemos mencionado anteriormente,

los Principals son asociados con un

Subject cuando tiene lugar una

autenticación exitosa.

Los Principals representan las

identidades de los Subjects, y deben

implementar las interfaces

java.security.Principal y

java.io.Serializable

JAAS

COMMON CLASSES: CREDENCIAL

Las clases que representan credenciales, tanto públicos como privados, no son parte de la librería JAAS.

Cualquier clase puede representar un credencial.

Los desarrolladores, sin embargo pueden decidir que sus clases credenciales implementen dos interfaces relacionadas con los credenciales que si son parte de la librería.

JAAS

COMMON CLASSES: CREDENCIAL

Refreshable

La interface javax.security.auth.Refreshable proporciona a un credencial la carcaterística de actualizarse a sí mismo. Por ejemplo, un credencial que caduca con el tiempo puede implementar esta interface para permitir a los llamantes actualizar el periodo de tiempo durante el cuál es válido.

Método Descripción

boolean isCurrent();Este método determina si el credencial

es válido o esta caducado.

void refresh() throws

RefreshFailedException;

Este método actualiza o aumenta el periodo de validez de un credencial. El método implementado debería ejecutar un AuthPermission ("refreshCredential") para asegurar que el llamante tiene permisos para actualizar el credencial

JAAS

COMMON CLASSES: CREDENCIAL

Destroyable

La interface javax.security.auth.Destroyable proporciona la

capacidad de destruir el contenido dentro de un credencial.

Método Descripción

boolean isDestroyed();Determina si el credencial ha sido

destruido.

void destroy() throws

DestroyFailedException;

Destruye y limpia la información asociada con el credencial. El método implementado debería ejecutar un AuthPermission ("destroyCredential")para asegurar que el llamante tiene permisos para destruir el credencial

JAAS

AUTHENTICATION CLASSES E INTERFACES

Para autenticar un subject (usuario o servicio), se ejecutan los siguientes pasos:

1. Una aplicación instancia un LoginContext

2. El LoginContext consulta un objeto de la clase Configuration para cargar todos los LoginModule configurados para esa aplicación.

3. La aplicación invoca al método login de la clase LoginContext

4. El método login invoca todos los LoginModule cargados. Cada LoginModule intenta autenticar al subject. Si se consigue autenticar, los LoginModules asocian los Principals y credenciales con un objeto Subject que representa al sujeto ya autenticado.

5. El LoginContext devuelve el estado (éxito o fallo) de la autenticación a la aplicación.

6. Si la autenticación fue exitosa, la aplicación recupera el Subject del LoginContext.

JAAS

AUTHENTICATION CLASSES E INTERFACES: LOGINCONTEXT

La clase javax.security.auth.login.LoginContextproporciona los métodos básicos para autenticar sujetos y la manera de desarrollar una aplicación independiente de la tecnología de autenticación subyacente.

El LoginContext consulta una Configuration para determinar los servicios de autenticación o LoginModules, configurados para una aplicación particular.

Asimismo, diferentes LoginModules pueden ser añadidos sin que se requiera ninguna modificación de la aplicación en sí misma.

JAASAUTHENTICATION CLASSES E INTERFACES: LOGINCONTEXT

Constructores:

public LoginContext(String name) throws LoginException;

public LoginContext(String name, Subject subject) throws

LoginException;

public LoginContext(String name, CallbackHandler callbackHandler)

throws LoginException

public LoginContext(String name, Subject subject,

CallbackHandler callbackHandler) throws LoginException

JAASAUTHENTICATION CLASSES E INTERFACES: LOGINCONTEXT

La autenticación en sí ocurre cuando se produce una llamada al siguiente método:

public void login() throws LoginException;

Cuando este método es invocado, todos los LoginModules configurados se invocan para ejecutar el proceso de autenticación. Si la autenticación es exitosa, el Subject (que puede ahora mantener Principals, credenciales públicas y credenciales privadas) puede ser recuperado usando el siguiente método:

public Subject getSubject();

Para ejecutar un logout sobre un Subject y borrar de esta manera, sus Principals y credenciales autenticados, debemos ejecutar el siguiente método:

public void logout() throws LoginException;

JAASAUTHENTICATION CLASSES E INTERFACES: LOGINCONTEXT

// let the LoginContext instantiate a new Subject

LoginContext lc = new LoginContext("entryFoo");

try {

// authenticate the Subject

lc.login();

System.out.println("authentication successful");

// get the authenticated Subject

Subject subject = lc.getSubject();

...

// all finished -- logout

lc.logout();

} catch (LoginException le) {

System.err.println("authentication unsuccessful: " +

le.getMessage());

}

JAAS

AUTHENTICATION CLASSES E INTERFACES: LOGINMODULE

El interface LoginModule da a los desarrolladores la habilidad de implementar diferentes tecnologías de autenticación que pueden ser conectadas en una aplicación.

Por ejemplo, un tipo de LoginModule puede ejecutar un formulario de autenticación basado en nombre de usuario y password. Otros LoginModules pueden servir de interface a dispositivos hardware tales como tarjetas inteligentes o dispositivos biométricos.

Los programadores de la aplicación normalmente no necesitan entender como trabajan los LoginModules.

Todo lo que deben saber es como especificar la información de configuración (como por ejemplo, un fichero de configuración de login), de manera que la aplicación pueda utilizar los LoginModule especificados en dicha configuración para autenticar al usuario.

JAASAUTHENTICATION CLASSES E INTERFACES: CALLBACKHANDLER

En algunos casos, los LoginModules deben comunicarse

con el usuario para obtener información.

Los LoginModules usan un

javax.security.auth.callback.CallbackHandler para este

propósito.

Las aplicaciones implementan el interfaz CallBackHandler

y los pasan al LoginContext (a través de los constructores

definidos para este propósito), el cúal los redirecciona

directamente a los LoginModule subyacentes

JAASAUTHENTICATION CLASSES E INTERFACES: CALLBACKHANDLER

Al permitir a la aplicación especificar el CallBackHandler, los LoginModules subyacentes pueden permanecer independientes de las distintas formas en que la aplicación interactúe con los usuarios.

Por ejemplo, la implementación de un CallBackHandler para una aplicación con una interfaz gráfica de usuario puede mostrar una pantalla para solicitar información a los usuarios, mientras que la implementación para una aplicación sin interfaz gráfica puede solicitar la información al usuario directamente desde línea de comandos.

JAASAUTHENTICATION CLASSES E INTERFACES: CALLBACKHANDLER

La interfaz CallBackHandler tiene un único método a implementar: void handle(Callback[] callbacks) throws java.io.IOException,

UnsupportedCallbackException;

El LoginModule pasa al método handle del CallBackHandler un array de los CallBacks usados por la aplicación para obtener los datos de entrada del usuario, por ejemplo un NameCallback para el nombre de usuario y un PasswordCallback para la contraseña

El CallBackHandler ejecuta la interacción solicitada con el usuario, estableciendo los valores capturados en los CallBack.

Por ejemplo, para procesar un NameCallBack, el CallBackHandler puede solicitar al usuario la introducción de un nombre, recuperar el valor introducido para el nombre y llamar al método setName de la clase NameCallBack para almacenarlo.

JAASAUTHENTICATION CLASSES E INTERFACES: CALLBACK

El paquete javax.security.auth.callback

contiene el interfaz CallBack, así como

varias implementaciones de la misma.

Algunas de estas implementaciones son

las anteriormente mencionadas:

NameCallback y PasswordCallback.

JAAS

AUTHORIZATION CLASSES

Para que una autorización JAAS tenga lugar, se requiere la siguiente situación:

1. El usuario debe estar autenticado

2. El Subject resultado de la autenticación debe estar asociado con un contexto de control de acceso

3. Deben estar configuradas las entradas referentes a qué Principals tienen permiso a qué recursos en el fichero de política de seguridad, como veremos más adelante.

JAAS

AUTHORIZATION CLASSES: POLICY

La clase java.security.Policy es una clase

abstracta para representar la política de

acceso del sistema. Por defecto, la J2SDK

proporciona una subclase basada en ficheros,

con soporte a entradas grant basadas en

Principals en ficheros de política

JAAS

AUTHORIZATION CLASSES: AUTHPERMISSION

La clase javax.security.auth.AuthPermission encapsula los

permisos básicos requeridos por JAAS

Además de los constructores proporcionados por su superclase

(java.security.Permission), la clase AuthPermission tiene estos

dos constructores:

public AuthPermission(String name);

public AuthPermission(String name, String actions);

JAASAUTHORIZATION CLASSES: AUTHPERMISSION

El primer constructor crea un nuevo AuthPermission con el nombre especificado.

El segundo también crea un nuevo AuthPermission, pero tiene un argumento adicional actions, que no debe ser usado y debería ser null. Este constructor existe solamente para que el objeto Policy pueda instaciar nuevos objetos de tipo Permission.

Para el resto, el primer constructor es el apropiado

Comúnmente el objeto AuthPermission se usa para proteger el acceso a los objetos Policy, Subject, LoginContext y Configuration. Para ello, en el parámetro nombre debemos especificar alguno de la lista siguiente:

JAASAUTHORIZATION CLASSES: AUTHPERMISSION

getSubject - allow for the retrieval of the

Subject(s) associated with the

current Thread.

setReadOnly - allow the caller to set a Subject

to be read-only.

modifyPrincipals - allow the caller to modify the Set

of Principals associated with a

Subject

modifyPublicCredentials - allow the caller to modify the

Set of public credentials

associated with a Subject

modifyPrivateCredentials - allow the caller to modify the

Set of private credentials

associated with a Subject

refreshCredential - allow code to invoke the refresh

method on a credential which implements

the Refreshable interface.

destroyCredential - allow code to invoke the destroy

method on a credential object

which implements the Destroyable

interface.

createLoginContext.{name} –

allow code to instantiate a LoginContext with the

specified name.

..... ......

JAAS

AUTHORIZATION CLASSES: PRIVATECREDENTIALPERMISSION

La clase javax.security.auth.PrivateCredentialPermission

protege el acceso a los credenciales privados de un Subject.

JAASCONFIGURACIÓN DEL FICHERO DE PROPIEDADES DE SEGURIDAD

JAVA.SECURITY JAVA_HOME/lib/security/java.security (Solaris)

JAVA_HOME\lib\security\java.security (Win32)

JAASCONFIGURACIÓN DEL FICHERO DE PROPIEDADES DE SEGURIDAD

JAVA.SECURITY

Login Configuration Provider

Si queremos especificar un proveedor de

Login específico debemos modificar la

siguiente propiedad del fichero java.security:

login.configuration.provider Si no se

especifica ningún valor a esta propiedad se

mantendrá el valor por defecto, es decir, se

usará el Login Provider proporcionado por

Sun, esto es:

login.configuration.provider=com.sun.securit

JAASCONFIGURACIÓN DEL FICHERO DE PROPIEDADES DE SEGURIDAD

JAVA.SECURITY

Login Configuration URLs Si estamos usando una configuración de login que espera que la

información de configuración sea especificada en ficheros (como la implementación por defecto de Sun), la localización de dichos ficheros puede ser estáticamente especificada mediante la propiedad login.config.url.n donde n, es una secuencia consecutiva de números comenzando por el 1 (tantos como ficheros de configuración usemos). Por ejemplo, para establecer dos ficheros de configuración de login: login.config.url.1=file:C:/config/.java.login.config

login.config.url.2=file:C:/users/foo/.foo.login.config

Si esta propiedad no es establecida estáticamente en el fichero java.security y tampoco es especificada dinámicamente desde línea de comandos (a través de la opción -Djava.security.auth.login.config), entonces JAAS cargará la cofiguración de login por defecto, localizada en la siguiente ruta: file:${USER_HOME}/.java.login.config

JAASCONFIGURACIÓN DEL FICHERO DE PROPIEDADES DE SEGURIDAD

JAVA.SECURITY

Policy Provider

Si queremos especificar un proveedor de

políticas alternativo al de por defecto

debemos modificar la siguiente propiedad

del fichero java.security:

policy.provider

Si no se especifica ningún valor a esta

propiedad se mantendrá el valor por defecto:

policy.provider=sun.security.provider.PolicyFile

JAASCONFIGURACIÓN DEL FICHERO DE PROPIEDADES DE SEGURIDAD

JAVA.SECURITY

Policy File URLs La localización de los ficheros de políticas puede ser

estáticamente especificada mediante la propiedad policy.url.n

Por ejemplo, para establecer dos ficheros de configuración de políticas: policy.url.1=file:C:/policy/.java.policy

policy.url.2=file:C:/users/foo/.foo.policy

Si esta propiedad no es establecida estáticamente ni dinámicamente desde línea de comandos (a través de la opción -Djava.security.policy), la política de control de acceso por defecto será obtenida del fichero de política del sistema que se creó cuando fue instalada la J2SDK, localizada en la siguiente ruta: JAVA_HOME/lib/security/java.policy (Solaris)JAVA_HOME

\lib\security\java.policy (Win32)

SEGURIDAD EN JAVAEE

La seguridad en Java EE está ampliamente basada en el API de JAAS (Java Authentication and Authorization Service)

JAAS esta diseñado para poder ejecutar los pasos de autenticación y autorización en cualquier capa JavaEE, incluyendo la capa web y la capa EJB

A la mayoría de las aplicaciones JavaEE se accede a través de la Web y se comparte la información de autenticación a través de todas las capas de la aplicación y no a través del servidor de aplicaciones.

JAAS esta en concordancia con esta realidad y, una vez que el usuario es autenticado en cualquier capa de la aplicación, el contexto de autenticación se pasa a través de las capas siempre que sea posible, en vez de repetir el paso de autenticación cada vez que se accede a un recurso protegido.

SEGURIDAD EN JAVAEE

El objeto Principal, que ya comentamos en el apartado dedicado a

JAAS, representa este contexto de autenticación validado y

compartible a lo largo de las capas de la aplicación.

SEGURIDAD EN JAVAEE

Un Escenario donde se plantea un problema de

Seguridad

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

La especificación Servlet de la capa web (http://java.sun.com/products/servlet) esconde un gran número de detalles de bajo nivel, tanto para el proceso de autenticación como para el proceso de autorización.

Como desarrollador, simplemente necesitas decirle al contenedor de Servlet del servidor de aplicaciones qué recursos quieres proteger, cómo protegerlos, cómo son pasados a través de las capas de la aplicación los credenciales de autenticación y qué roles tienen acceso a los recursos protegidos.

La seguridad en la capa Web es configurada principalmente usando los elementos login-config y security-constraint del fichero DD web.xml.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

El siguiente ejemplo muestra como proteger el módulo de Administración de la aplicación de subastas

<login-config><auth-method>BASIC</auth-method> (1)<realm-name>ActionBazaarRealm</realm-name> (2)

</login-config>...<security-constraint>

<web-resource-collection><web-resource-name>

ActionBazaar Administrative Component</web-resource-name><url-pattern>/admin/*</url-pattern> (3)

</web-resource-collection><auth-constraint>

<role-name>CSR</role-name> (4)</auth-constraint>

</security-constraint>

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA

WEB

BASIC (HTTP Basic Authentication) (I)

1. Un cliente solicita acceso a un recurso protegido

2. El servidor devuelve una ventana de diálogo, que solicita el nombre de usuario y contraseña

3. El cliente submite el nombre de usuario y password al servidor

4. El servidor autentica al usuario en el reino especificado y, en caso de éxito, devuelve el recurso solicitado.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

BASIC (HTTP Basic Authentication) (II)

No seguro

Basic Authentication envía el nombre de usuario y contraseña a través

de Internet como texto plano codificado en Base64 y, además, el

servidor de destino no esta autenticado. Si alguien consigue interceptar

la transmisión, el nombre de usuario y contraseña pueden ser

fácilmente decodificados.

Sin embargo, cuando se usa un protocolo de transmisión seguro, como

SSL en conjunción con la basic authentication se puede reducir este

problema.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

FORM (Form-Based Authentication) (I)

La autenticación basada en formularios permite al

desarrollador controlar el aspecto de las pantallas

de login, permitiendo personalizar las pantallas de

login y error que el navegador presenta al usuario

final

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA

WEB

FORM (Form-Based Authentication) (II)

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

FORM (Form-Based Authentication) (III)

Configuración:

<login-config>

<auth-method>FORM</auth-method>

<realm-name>file</realm-name>

<form-login-config>

<form-login-page>/logon.jsp</form-login-

page>

<form-error-page>/logonError.jsp</form-

error-page>

</form-login-config>

</login-config>

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

FORM (Form-Based Authentication) (IV)

Cuando codifiquemos un login usando el método FORM para

autenticación, el action del formulario de login debe ser

siempre j_security_check. En este trozo de código vemos estas

restricciones de codificación

<form method="POST"

action="j_security_check">

<input type="text" name="j_username">

<input type="password" name="j_password">

</form>

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

FORM (Form-Based Authentication) (V)

Form-based Authentication envía el nombre de usuario y contraseña a

través de Internet como texto plano y, además, el servidor de destino no

esta autenticado. Si alguien consigue interceptar la transmisión, el

nombre de usuario y contraseña pueden ser fácilmente decodificados.

Sin embargo, cuando se usa un protocolo de transmisión seguro, como

SSL en conjunción con el form-based authentication se puede reducir

este problema.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

CLIENT-CERT (HTTPS Client Authentication) (I) Requiere que el cliente posea un certificado de clave pública

(PKC – Public Key Certificate).

Si especificamos este tipo de autenticación, el servidor autenticará al cliente usando su certificado de clave pública.

HTTPS Client Authentication es el método más seguro de autenticación. Usa HTTP sobre SSL (HTTPS). La tecnología SSL (Secure Sockets Layer) proporciona encriptación de datos, autenticación del servidor, integridad de los mensajes y autenticación de cliente opcional para una conexión TCP/IP.

Podemos pensar en una PKC como el equivalente digital de un pasaporte.

Es emitida por una organización de confianza, denominada Certificate Authority (CA).

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

CLIENT-CERT (HTTPS Client Authentication) (II)

Antes de usar HTTPS Client Authentication, debemos

comprobar que las siguientes acciones han sido completadas:

El servidor ha sido configurado para soportar SSL

Asegurarse de que el cliente tiene una PKC válida.

<login-config>

<auth-method>CLIENT-CERT</auth-method>

</login-config>

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

CLIENT-CERT (HTTPS Client Authentication) (III)

Dos tipos:

Mutual Authentication: Con la autenticación

mutua, el cliente y el servidor se autentican el

uno al otro. Existen dos tipos de autenticación

mutua

Digest Authentication: Como la BASIC

Authentication, pero transmitiendo la contraseña

encriptada con un protocolo más complejo que la

codificación Base64. Su uso no está demasiado

extendido y la mayoría de los AS no la

implementan

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA WEB

CLIENT-CERT (HTTPS Client Authentication) (IV)

Mutual Authentication. Dos tipos:

Certificate-based mutual authentication

User name- and password-based mutual

authentication

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA

WEB

Certificate-based mutual authentication

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EN LA CAPA

WEB

User name- and password-based mutual authentication

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

El modelo de autenticación y autorización

proporcionado por la especificación EJB3 tiene

dos enfoques:

Declarativo

Programático

Estudiaremos ambos enfoques codificando el

escenario planteado anteriormente (cancelar

una puja)

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa

En nuestra capa de lógica de negocio, para el escenario planteado,

tenemos un EJB de sesión sin estado, que se encarga de la gestión de

las pujas en las subastas; éste EJB se llama BeanManagerBean.

Sin aplicar reglas de seguridad cualquier usuario podrá ejecutar el

código asociado con el método cancelBid.

En el siguiente pedazo de código mostramos la solución desde una

aproximación declarativa

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa

@DeclareRoles({"BIDDER", "CSR", "ADMIN"}) (1)@Stateless

public class BidManagerBean implements BidManager {

@RolesAllowed({"CSR, ADMIN"}) (2)

public void cancelBid(Bid bid, Item item) {...}

@PermitAll (3)public List<Bid> getBids(Item item) {...}

}

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa: @DeclareRoles Es muy recomendable que declaremos los roles de seguridad que

serán empleados en nuestra aplicación, modulo EJB, EJB o en nuestros métodos de negocio.

Existen varias maneras de declarar roles, una de ellas es a través de la anotación @DeclareRoles, que usamos en el punto (1). Esta anotación se puede aplicar a nivel de clase o a nivel de método y consta de un array de nombres de roles.

En el ejemplo, estamos indicando que el EJB BidManagerBean usa los roles BIDDER, CSR y ADMIN.

De manera alternativa, podríamos haber especificado los roles para toda la aplicación o para todo el módulo EJB a través de los descriptores de despliegue.

Si no hacemos una declaración explícita de los roles de la aplicación en ningún lado, el contenedor construirá automáticamente una lista de roles, inspeccionando la anotación @RolesAllowed.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa: @RolesAllowed

La anotación @RolesAllowed es la más importante del enfoque declarativo en la gestión de la seguridad.

Esta anotación puede ser aplicada a nivel de método o a nivel de clase.

Cuando se aplica a nivel de clase (EJB), le dice al contenedor que roles tienen permiso para acceder a cualquier método del EJB.

Por otro lado, podemos usar esta anotación en un método para especificar la lista de roles permitidos para ese método en particular.

En el ejemplo (2) estamos especificando que sólo los roles CSR y ADMIN tienen permiso para cancelar pujar a través del método cancelBid

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa: @PermitAll

Podemos usar la anotación @PermitAll a nivel de clase o a

nivel de método para indicar que puede ser invocado por

cualquier rol.

En el ejemplo (3) usamos esta anotación para indicar al

contenedor que cualquier usuario puede recuperar las pujas

realizadas hasta ahora para un artículo dado.

Deberíamos usar esta anotación con moderación, sobre todo a

nivel de clase, ya que es posible dejar agujeros de seguridad

que pasen inadvertidos.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa: @DenyAll

La anotación @DenyAll hace justamente lo contrario que @PermitAll.

Un escenario al que sería aplicable esta, en principio inútil, anotación podría ser cuando consideras el hecho de que tu aplicación puede ser desplegada en un gran número de entornos que desconoces. Podrías sencillamente invalidar un determinado método para un entorno en particular, sin necesidad de cambiar el código, aplicándole esta anotación.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa: @RunAs (I)

Esta anotación es muy útil cuando necesitamos asignar un nuevo rol dinámicamente al Principal en el alcance de la invocación de un método EJB.

Esto puede ser necesario, por ejemplo, si estas invocando a otro EJB dentro de tu método pero el otro EJB requiere un rol diferente al del actual Principal.

Dependiendo de la situación, el nuevo rol asumido puede ser más restrictivo, menos o ninguno

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad declarativa: @RunAs (II) El método cancelBid podría necesitar invocar un EJB que

gestione un registro histórico con la finalidad de obtener datos estadísticos del número de pujas canceladas. Sin embargo, el EJB que gestiona el histórico sólo puede ser accedido con el rol de ADMIN.

Usando la anotación @RunAs, podemos asignar a un CSR el rol de ADMIN temporalmente, de manera que el EJB encargado del histórico piense que un ADMIN esta invocando uno de sus métodos

@RunAS("ADMIN")@RolesAllowed("CSR")public class BidManagerBean implements

BidManager {

public void cancelBid(Bid bid, Item item)

{...}

}

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad programática (I)

El problema con la seguridad declarativa viene cuando

necesitas implementar distintos tipos de acciones en función

del rol de un Principal, es decir, necesitas cambiar el

comportamiento de ciertos métodos en función del rol del

usuario que intenta ejecutar ese código

La seguridad programática nos permite ir más allá en la

implementación de la seguridad en nuestra aplicación, gracias

al hecho de que tenemos acceso directo al Principal desde

nuestro código.

El acceso al Principal se hace a través del contexto EJB

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad programática (II)

@Statelesspublic class BidManagerBean implements BidManager {

@Resource SessionContext context; (1)...public void cancelBid(Bid bid, Item item) {

if (!context.isCallerInRole("CSR")) { (2)

throw new SecurityException( "No permissions to cancel bid"); (3)

}...

}...

}

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad programática (III)

El interfaz EJBContext nos proporciona los siguientes métodos

relacionados con la gestión de la seguidad:

public interface EJBContext {

...

public java.security.Principal getCallerPrincipal();

public boolean isCallerInRole(java.lang.String roleName);

...

}

El método getCallerPrincipal() nos da acceso directo al interfaz

java.security.Principal que representa el contexto de

autenticación actual.

SEGURIDAD EN JAVAEEAUTENTICACIÓN Y AUTORIZACIÓN EJB

Seguridad programática (IV) El único método de interés de la interfaz Principal es el método getName(),

que devuelve el nombre del principal, que, en la mayoría de los casos, suele el nombre del usuario autenticado.

Para mostrar un ejemplo de uso de este método, imaginemos que cambiamos los requisitos de nuestro escenario de ejemplo y ahora, además de los CSRs, los compradores también pueden cancelar sus propias pujas

public void cancelBid(Bid bid, Item item) {if (!context.isCallerInRole("CSR")

&& !(context.getCallerPrincipal().getName().equals(

bid.getBidder().getUsername()) && (bid.getTimestamp() >=

(getCurrentTime() - 60*1000))))) {

throw new SecurityException("No permissions to cancel bid");

}

...}