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
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 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");
}
...}
Top Related