Download Anotaciones

Document related concepts
no text concepts found
Transcript
DEPARTAMENTO DE SISTEMAS
Arquitectura de Software
Session Beans
ISIS3702
Agenda
DEPARTAMENTO DE SISTEMAS
•  Anotaciones
•  Java Naming Directory Interface (JNDI)
•  Session Beans
Anotaciones
DEPARTAMENTO DE SISTEMAS
 
 
Evitar la división de artefactos
programación en varios archivos
 
Implementación – Interface
 
Archivos descriptores separados
de
Definir un mecanismo estándar para
anotar archivos de clases Java
Anotaciones
DEPARTAMENTO DE SISTEMAS
 
Las anotaciones no afectan directamente la
semántica de un programa. (no son usadas por la
JVM)
 
Sí afectan cómo el código es usado por herramientas,
librerías y frameworks.
 
Pueden ser leídas del código fuente, archivos de
clase o durante la ejecución
Anotaciones
DEPARTAMENTO DE SISTEMAS
 
Una anotación es un tipo especial de modificador y
puede ser usada en cualquier lugar que se usen otros
modificadores ( como public, static o final)
 
Por convención
modificadores
 
Consisten de un signo de arroba (@) seguido del tipo
de la anotación y una lista en paréntesis de pares
elemento-valor
se
ponen
antes
que
otros
Anotaciones
DEPARTAMENTO DE SISTEMAS
 
Atributos
public class SomeClass{
@Resource
(name=“customerDB”)
private DataSource myDb;…
}
 
Métodos
public class SomeClass{
private DataSource myDb;
@Resource
(name=“customerDB”)
private void setMyDB(…)
{...}
...
}
  Clases
@Resource
(name=“MyMessageQueue”
,
type=“ConnectionFactor
”)
public class SomeClass{
...
}
Anotaciones
DEPARTAMENTO DE SISTEMAS
•  Definición
o 
@interface
•  Tipos
o 
o 
o 
Marker
Single-Element
Multi-value
public @interface MyAnnotation {
String doSomething();
}
@MyAnnotation
public void mymethod() {
....
}
@MyAnnotation ("What to do")
public void mymethod() {
....
}
Anotaciones
DEPARTAMENTO DE SISTEMAS
•  Anotation Driven Code Instrumentation
o 
o 
o 
o 
o 
Annotation Processing Tool (APT)
Utilidad para procesar anotaciones
Incluye un API reflexivo
No ermite modificar le código fuente
Se puede modificar el byte code
Anotaciones
DEPARTAMENTO DE SISTEMAS
public class SimpleTransformer {
public static void main(String[] args) throws Exception {
SimpleTransformer transformer = new SimpleTransformer();
transformer.transform(args[0], args[1]);
}
public void transform(String input, String output) throws IOException {
writeClassData(transform(readClassData(input)), output);
}
private byte[] transform(byte[] code) {
ClassReader reader = new ClassReader(code);
ClassNode classNode = new ClassNode();
reader.accept(classNode, true);
classNode.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "myNewField",
"I", null, null));
ClassWriter writer = new ClassWriter(false);
classNode.accept(writer);
return writer.toByteArray();
}
}
Tomado de : http://llhours.free.fr/drupal/?q=node/15
Agenda
DEPARTAMENTO DE SISTEMAS
•  Anotaciones
•  Java Naming Directory Interface (JNDI)
•  Session Beans
JNDI
DEPARTAMENTO DE SISTEMAS
 
Acceso desde un componente a otros componentes o recursos
(e.g., bases de datos)
 
Un servlet puede invocar métodos remotos de un enterprise bean
que consulta información de una bd
 
JNDI es un servicio de nombres que permite a un componente
localizar otros componentes o recursos
 
Habilita a las aplicaciones para acceder múltiples servicios de
nombres y de directorios. Por ejemplo servicios como LDAP,
NDS,DNS, y NIS.
 
Ofrece los métodos de
 
 
 
Asociar un nombre con un objeto (binding)
Buscar un objeto (lookup)
El uso de JNDI en aplicaciones Java EE permite almacenar o
consultar cualquier objeto de java: acceso a sistemas y
aplicaciones Legado
JNDI
DEPARTAMENTO DE SISTEMAS
 
Un administrador crea un recurso en un namespace de JNDI
 
En el servidor de aplicaciones se pueden crear recursos con la consola de
administración o el comando asadmin
 
Las aplicaciones utilizan anotaciones para acceder a los recursos. Cuando
una aplicación utiliza la “inyección” del recurso, el servidor de aplicaciones
invoca el API JNDI (@Resource)
 
La aplicación puede hacer llamados directos del API JNDI
 
Un recurso y su nombre JNDI son ligados por el servicio de nombres
 
Un recurso nuevo es creado en JNDI con la asociación del nombre del
recurso en el namespace de JNDI (bind del recurso)
 
Namespace: conjunto de todos los nombres de un servicio de nombres
JNDI
DEPARTAMENTO DE SISTEMAS
•  @EJB
o 
o 
Declaración del atributo
Método Setter
•  Atributos Opcionales
o 
beanName
 
 
o 
beanInterface
 
o 
Nombre de la clase
Ejb-name si el EJB tiene un descriptor XML
Interface local o remota
mappedName
 
Nombre JNDI
JNDI
DEPARTAMENTO DE SISTEMAS
Partes de un @Resource
 
 
 
 
 
 
name: nombre del recurso en JNDI
type: el tipo (Java) del recurso
authenticationType: tipo de autenticación para utilizar el recurso
shareable: indica si el recurso puede ser compartido
mappedName: nombre específico de la implementación que indica que el recurso
puede ser mapeado a
description: descripción del recurso
Ejemplos de estilos de inyección: atributos, métodos y clases
  Atributos:
public class SomeClass { @Resource(name="customerDB")
private javax.sql.DataSource myDB; ... }
  Métodos
public class SomeClass { private javax.sql.DataSource myDB; ...
@Resource(name="customerDB")
private void setMyDB(javax.sql.DataSource ds) { myDB = ds; }
  Clases
@Resource(name="myMessageQueue", type="javax.jms.ConnectionFactory")
public class SomeMessageBean { …}
JNDI - Ejemplo
DEPARTAMENTO DE SISTEMAS
 
Acceso a una base de datos con el API JDBC: recurso JDBC con información
sobre
 
 
 
Servidor de BD
Nombre de la BD
Protocolo de red utilizado para la comunicación
 
Un objeto DataSource es una fábrica de conexiones de una fuente de datos
específica. El método getConnection retorna una conexión física a la fuente de
datos
 
Si el objeto DataSource es registrado con JNDI, una aplicación puede utilizar el
API JNDI (lookup) para obtener el objeto y posteriormente conectarse a la
fuente de datos
 
Las aplicaciones utilizando el API de persistencia especifican la fuente de
datos en el archivo persistence.xml
<jta-data-source>jdbc/MyOrderDB</jta-data-source>
 
Este punto es el único que referencia algo sobre el objeto JDBC
JNDI
DEPARTAMENTO DE SISTEMAS
• 
Los servicios de nombres de Java EE proveen ambientes de nombres JNDI a
las aplicaciones cliente, enterprise beans, y componente web
• 
Un naming environment permite personalizar a un componente sin acceder o
cambiar el código fuente de los componentes
• 
Un contenedor implementa el ambiente de los componentes como un contexto
de nombres
• 
Contexto es un objeto cuyo estado tiene asociados un conjunto de relaciones
entre nombres y objetos (bindings)
• 
Un contexto tiene asociado una convención de nombres
• 
Contexto inicial es el punto de partida para hacer las operaciones
• 
En JNDI todas las operaciones son realizadas en un contexto
JNDI
DEPARTAMENTO DE SISTEMAS
 
Un componente Java EE puede localizar su contexto de nombres con JNDI
 
Un componente puede crear un objeto javax.naming.InitialContext y buscar
su contexto bajo el nombre de java:comp/env.
 
Un componente Java EE puede acceder nombres provistos por el sistema
(named system-provided) y objetos definidos por los usuarios (user-defined
objects)
 
Nombres de objetos provistos por el sistema (e.g., objetos JTA) son
almacenados en el contexto java:comp/env
 
Según el tipo de objeto a definir por el usuario el subcontexto para
registrarlo varía
 
 
Enterprise beans: java:comp/env/ejb
JDBC DataSource: java:comp/env/jdbc
JNDI
DEPARTAMENTO DE SISTEMAS
 
Ejemplo con propiedades del ambiente
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, args[2]); //rmi://localhost:1099
Context ctxt = new InitialContext(env);
Compute comp = (Compute) ctxt.lookup(name);
 
Ejemplo con archivo de configuración de las propiedades
Context initial = new InitialContext();
Object objref = initial.lookup("java:comp/env/ejb/SimpleConverter”);
Archivo build.xml
<target name="run" depends="buildjar">
<java fork="true" classname="client.ComputePi">
<classpath path="${build}" />
<classpath path="${compute}" />
…
<sysproperty key="java.naming.factory.initial"
value="com.sun.jndi.rmi.registry.RegistryContextFactory" />
<sysproperty key="java.naming.provider.url" value="rmi://${hostname}:${port}" />
</java>
</target>
JNDI
DEPARTAMENTO DE SISTEMAS
 
Las propiedades del ambiente JNDI se deben configurar de
acuerdo con las características del proveedor del servicio que
se va a utilizar
 
Las propiedades se clasifican en:
  Estándares (java.naming……): java.naming.factory.initial
  Específicas del servicio (java.naming.service……):
java.naming.corba.orb
  Característica específica (java.naming.feature….):
java.naming.security.sasl
  Especificas del proveedor: com.sun.jndi.ldap.trace.ber
JNDI
DEPARTAMENTO DE SISTEMAS
 
java.naming.factory.initial
 
 
 
nombre de la clase de la fábrica del contexto inicial
La clase debe implementar la interface
InitialContextFactory
Ejemplo valores:
 
 
com.sun.jndi.ldap.LdapCtxFactory
com.sun.jndi.rmi.registry.RegistryContextFactory
JNDI
DEPARTAMENTO DE SISTEMAS
 
java.naming.provider.url
 
 
El URL para configurar el proveedor del servicio
definido en la propiedad "java.naming.factory.initial"
Ejemplo valores:
 
 
ldap://localhost:389/o=JNDITutorial
rmi://localhost:1099
Agenda
DEPARTAMENTO DE SISTEMAS
•  Anotaciones
•  Java Naming Directory Interface (JNDI)
•  Session Beans
Session Beans
DEPARTAMENTO DE SISTEMAS
 
Representa un cliente de la aplicación o una sesión
de un cliente
 
Ofrece un conjunto de métodos para la interacción
entre un cliente y una aplicación
 
No es compartido entre clientes
 
No es persistente, opuesto a los beans de entidad
Session Beans
DEPARTAMENTO DE SISTEMAS
 
Con estado (stateful)
 
 
 
 
 
 
El estado del bean representa la interacción entre un cliente específico
y el bean
El estado del bean o conjunto de atributos se mantiene durante toda la
sesión del cliente
Al terminar la sesión el estado no se conserva
El contenedor puede almacenarlos en memoria secundaria
Puede implementar servicios web
Sin estado (stateless)
 
 
 
 
 
El estado del bean se conserva únicamente durante la ejecución del
método invocado
Todo bean tiene el mismo estado antes de ser invocado
El contenedor de EJB puede seleccionar cualquier bean para ejecutar
un método
Es apropiado para brindar la escalabilidad de aplicaciones ya que
puede soporta múltiples clientes
Nunca son almacenados en memoria secundaria
Session Beans
DEPARTAMENTO DE SISTEMAS
 
Qué es el estado de un bean de sesión. Dé
ejemplos
 
Una clase que representa un bean de sesión
sin estado puede tener atributos?
 
El mismo bean de sesión puede implementarse
con o sin estado?. Dé un ejemplo
 
En la hoja de trabajo entregada, identifique las
diferencias entre un bean de sesión con y sin
estado
Session Beans
DEPARTAMENTO DE SISTEMAS
 
Un bean de sesión requiere una clase
 
Todo bean de sesión que permita su acceso remoto debe tener una
interfaz de negocios remota
 
Los métodos de negocio
 
 
 
 
 
 
El nombre no puede comenzar con ejb. Esto evita conflictos con los
métodos callback (ejbCreate, ejbActivate)
Deben ser públicos
Si el bean para su acceso de forma remota utilizó una interfaz de
negocios remota, los tipos de retorno y los parámetros deben ser tipos
válidos de Java RMI
No pueden ser ni static ni final
Para indicar problemas como incapacidad para conectarse a la BD,
debe incluir throw javax.ejb.EJBException
Un bean de sesión para brindar los requerimientos funcionales de
una aplicación
puede necesitar de clases helper
(ManejoExcepciones y verificaciones)
Session Beans
DEPARTAMENTO DE SISTEMAS
 
 
Ejemplo - Intermediario
 
El bean representa un carro de compras en una tienda en
línea
 
El cliente puede adicionar, borrar o consultar el contenido del
carro de compras
Archivos:
 
 
 
 
Interfaz remota (Cart.java)
Clase enterprise bean (CartBean.java)
Clase cliente (CartClient.java)
Clases Helper (BookException.java and IdVerifier.java).
Session Beans - Ejemplo cart.java
DEPARTAMENTO DE SISTEMAS
import java.util.List;
import javax.ejb.Remote;
@Remote
Métodos del negocio
public interface Cart {
public void initialize(String person) throws BookException;
public void initialize(String person, String id) throws
BookException;
public void addBook(String title);
public void removeBook(String title) throws BookException;
public List<String> getContents();
public void remove();
}
Session Beans - cartBean.java
DEPARTAMENTO DE SISTEMAS
 
Clase bean del ejemplo
  Implementa la interface de negocio
  Tiene la anotación @Stateful.
  Implementa los métodos de negocios definidos en la interface
de negocios
 
Los beans con estado adicionalmente
  Pueden implementar cualquier método de callback, anotados
con @PostConstruct, @PreDestroy, @PostActivate o
@PrePassivate
  Implementan cualquier método opcional anotado con
@Remove
Session Beans - cartBean.java (2)
DEPARTAMENTO DE SISTEMAS
import javax.ejb.Remove;
import javax.ejb.Stateful;
@Stateful
public class CartBean implements Cart
{
String customerName;
String customerId;
List<String> contents;
public void initialize(String person)
throws BookException {
if (person == null) {
throw new BookException("Null
person not allowed.");
} else {
customerName = person;
}
customerId = "0";
contents = new ArrayList<String>();
}
//id: parametro String id de initialize
IdVerifier idChecker = new IdVerifier();
if (idChecker.validate(id)) {
customerId = id;
} else {
throw new BookException("Invalid
id: " + id);
}
public void addBook(String title) {
contents.add(title);
}
@Remove
public void remove() {
contents = null;
}
Session Beans - Anotaciones
DEPARTAMENTO DE SISTEMAS
 
Interface
 
 
 
@Remote: indica que se trata de una interfaz de negocio remota
@Local: acceso al bean de forma local únicamente
Clase
 
@stateless similar a @stateful /* bean de sesión con estado */
  Indica que el bean de sesión es sin estado
  Dependiendo del contenedor
 
 
 
Se crea el stub del bean
Registra en JNDI el bean con el nombre lógico "java:comp/env/ejb/
nombreBean“ o con un nombre dado en la anotación
@EJB
  Aplica para interfaces remotas únicamente
  Genera el lookup del bean de sesión en JNDI con el nombre "java:comp/
env/ejb/nombreBean“
  En serviciosCliente.java
@EJB(name = "co.com.uniandes.ejemplo.servicios.IServiciosProducto")
private IServiciosProducto serviciosProducto;
 
@Resource
  Inyección de recursos
  @Resource(name="jdbc/sqetestDB",type=javax.sql.DataSource.class)
public javax.sql.DataSource myTestDB;
Session Beans - Anotaciones
DEPARTAMENTO DE SISTEMAS
• 
• 
• 
• 
• 
@PostConstruct
@PrePassivate
@PreDestroy
@PostActivate
@Init
Session Beans
DEPARTAMENTO DE SISTEMAS
 
Métodos de Callback son invocados por el contenedor relacionados
con el ciclo de vida del bean
 
Deben ser públicos, sin retorno (void), y sin parámetros.
 
Utilizan las siguientes anotaciones
 
@PostConstruct: invocado sobre una instancia recientemente creada después
de la inyección (o JNDI lookup) de todas las dependencias y antes de la
invocación del primer método (javax.annotation.PostConstruct)
 
@PreDestroy: invocado luego de que un método anotado con @Remove ha
terminado y antes de que el contenedor elimine la instancia del bean
(javax.annotation.PreDestroy)
 
@PrePassivate: invocado antes de que el contenedor desactive (passivave) el
bean, el contenedor elimina temporalmente el bean y lo salva en memoria
secundaria (javax.ejb.PrePassivate)
 
@PostActivate: invocado después de que el contenedor mueve el bean de
memoria secundaria a estado activo (active) (javax.ejb.PostActivate)
Ciclo de vida bean con estado
DEPARTAMENTO DE SISTEMAS
El método remove es el único
que es invocado directamente
por el cliente
El contendor decide
desactivar el bean
El cliente inicia el
ciclo de vida
obteniendo una
referencia al bean de
sesión -stateful
1.
2.
El cliente invoca
algún método del
negocio durante la
desactivación
Ciclo de vida bean sin estado
DEPARTAMENTO DE SISTEMAS
El cliente inicia el
ciclo de vida
obteniendo una
referencia al bean de
sesión -stateful
1.
JEE – EJB3/ Security
DEPARTAMENTO DE SISTEMAS
•  EJB3 Security
o 
El contenedor ofrece un servicio de seguridad para
toda la aplicación
o 
Es posible configurar los permisos de usuario para
cada llamado de un método usando solamente
anotaciones
o 
Basado en el Java Authentication
Authorization Service (JAAS)
and
JEE – EJB3/ Security
DEPARTAMENTO DE SISTEMAS
JEE – EJB3/ Security
DEPARTAMENTO DE SISTEMAS
•  EJB3 Security
o 
Nombres de Usuarios y Passwords
 
Servidores LDAP
 
Servidores de Bases de Datos
 
Archivos Texto (properties)
 
users.properties
 
roles.properties
 
Debe estar en el path de la aplicación
admin=jboss
user=ejb3
admin=AdminUser,RegularUser
user=RegularUser
JEE – EJB3/ Security
DEPARTAMENTO DE SISTEMAS
•  EJB3 Security
o 
o 
o 
o 
Annotations
Sirven para especificar dónde encontrar la lista de roles y
passwords
Definen que roles y usuarios están permitidos para ejecutar un
método
@SecurityDomain (“other”)
 
o 
@RolesAllowed()
 
o 
Anota métodos que no serán verificados con restricciones de seguridad
@DenyAll
 
o 
Especifica los roles permitidos a ejecutar cada métodos
@PermitAll
 
o 
Indica que se usaran los archivos de properties para el manejo de la
seguridad
Ningún rol está autorizado para llamar este método
DeclareRoles
 
Roles definidos en una clase
JEE – EJB3/ Security
DEPARTAMENTO DE SISTEMAS
public interface Calculator {
int add(int x, int y);
int subtract(int x, int y);
int divide(int x, int y);
}
@Stateless
@SecurityDomain("other")
public class CalculatorBean implements Calculator {
@PermitAll
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public int add(int x, int y) {
return x + y;
}
@RolesAllowed({"student"})
public int subtract(int x, int y) {
return x - y;
}
@RolesAllowed({"teacher"})
public int divide(int x, int y) {
return x / y;
}
}
JEE – EJB3/ Security
DEPARTAMENTO DE SISTEMAS
public class Main {
public static void main(String[] args) throws Exception {
EJB3StandaloneBootstrap.boot(null);
EJB3StandaloneBootstrap.deployXmlResource("security-beans.xml");
EJB3StandaloneBootstrap.scanClasspath();
// Establish the proxy with an incorrect security identity
Properties env = new Properties();
env.setProperty(Context.SECURITY_PRINCIPAL, "kabir");
env.setProperty(Context.SECURITY_CREDENTIALS, "invalidpassword");
env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
InitialContext ctx = new InitialContext(env);
Calculator calculator = (Calculator) ctx.lookup("CalculatorBean/local");
System.out.println("Kabir is a student.");
System.out.println("Kabir types in the wrong password");
try {
System.out.println("1 + 1 = " + calculator.add(1, 1));
}
catch (EJBAccessException ex)
{
System.out.println("Saw expected SecurityException: " + ex.getMessage());
}
JEE – EJB3/ Security
DEPARTAMENTO DE SISTEMAS
System.out.println("Kabir types in correct password.");
System.out.println("Kabir does unchecked addition.");
// Re-establish the proxy with the correct security identity
env.setProperty(Context.SECURITY_CREDENTIALS, "validpassword");
ctx = new InitialContext(env);
calculator = (Calculator) ctx.lookup("CalculatorBean/local");
System.out.println("1 + 1 = " + calculator.add(1, 1));
System.out.println("Kabir is not a teacher so he cannot do division");
try {
calculator.divide(16, 4);
}
catch (javax.ejb.EJBAccessException ex) {
System.out.println(ex.getMessage());
}
System.out.println("Students are allowed to do subtraction");
System.out.println("1 - 1 = " + calculator.subtract(1, 1));
}
}
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
@Stateful(name = "Movies")
public class MoviesImpl implements Movies {
@PersistenceContext(unitName = "movie-unit", type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;
@RolesAllowed({"Employee", "Manager"})
public void addMovie(Movie movie) throws Exception {
entityManager.persist(movie);
}
@RolesAllowed({"Manager"})
public void deleteMovie(Movie movie) throws Exception {
entityManager.remove(movie);
}
@PermitAll
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public List<Movie> getMovies() throws Exception {
Query query = entityManager.createQuery("SELECT m from Movie as m");
return query.getResultList();
}
}
Tomado de: http://openejb.apache.org/3.0/testing-security-example.html
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
public class MovieTest extends TestCase {
private Context context;
protected void setUp() throws Exception {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
p.put("movieDatabase", "new://Resource?type=DataSource");
p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb");
p.put("movieDatabaseUnmanaged", "new://Resource?type=DataSource");
p.put("movieDatabaseUnmanaged.JdbcDriver", "org.hsqldb.jdbcDriver");
p.put("movieDatabaseUnmanaged.JdbcUrl", "jdbc:hsqldb:mem:moviedb");
p.put("movieDatabaseUnmanaged.JtaManaged", "false");
context = new InitialContext(p);
}
Tomado de: http://openejb.apache.org/3.0/testing-security-example.html
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
public void testAsManager() throws Exception {
Caller managerBean = (Caller) context.lookup("ManagerBeanLocal");
managerBean.call(new Callable() {
public Object call() throws Exception {
Movies movies = (Movies) context.lookup("MoviesLocal");
movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
movies.addMovie(new Movie("Joel Coen", "The Big Lebowski", 1998));
List<Movie> list = movies.getMovies();
assertEquals("List.size()", 3, list.size());
for (Movie movie : list) {
movies.deleteMovie(movie);
}
assertEquals("Movies.getMovies()", 0, movies.getMovies().size());
return null;
}
}); }
Tomado de: http://openejb.apache.org/3.0/testing-security-example.html
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
public void testAsEmployee() throws Exception {
Caller employeeBean = (Caller) context.lookup("EmployeeBeanLocal");
employeeBean.call(new Callable() {
public Object call() throws Exception {
Movies movies = (Movies) context.lookup("MoviesLocal");
movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
movies.addMovie(new Movie("Joel Coen", "The Big Lebowski", 1998));
List<Movie> list = movies.getMovies();
assertEquals("List.size()", 3, list.size());
for (Movie movie : list) {
try {
movies.deleteMovie(movie);
fail("Employees should not be allowed to delete");
} catch (EJBAccessException e) {
// Good, Employees cannot delete things
}
}
assertEquals("Movies.getMovies()", 3, movies.getMovies().size());
return null;
}
}); }
Tomado de: http://openejb.apache.org/3.0/testing-security-example.html
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
public void testUnauthenticated() throws Exception {
Movies movies = (Movies) context.lookup("MoviesLocal");
try {
movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
fail("Unauthenticated users should not be able to add movies");
} catch (EJBAccessException e) {
// Good, guests cannot add things
}
try {
movies.deleteMovie(null);
fail("Unauthenticated users should not be allowed to delete");
} catch (EJBAccessException e) {
// Good, Unauthenticated users cannot delete things
}
try {
// Read access should be allowed
List<Movie> list = movies.getMovies();
} catch (EJBAccessException e) {
fail("Read access should be allowed");
}}
Tomado de: http://openejb.apache.org/3.0/testing-security-example.html
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
public static interface Caller {
public <V> V call(Callable<V> callable) throws Exception;
}
/**
* This little bit of magic allows our test code to execute in
* the desired security scope.
* <p/>
* The src/test/resource/META-INF/ejb-jar.xml will cause this
* EJB to be automatically discovered and deployed when
* OpenEJB boots up.
*/
@Stateless
@RunAs("Manager")
public static class ManagerBean implements Caller {
public <V> V call(Callable<V> callable) throws Exception {
return callable.call();
}
}
@Stateless
@RunAs("Employee")
public static class EmployeeBean implements Caller {
public <V> V call(Callable<V> callable) throws Exception {
return callable.call();
}
}}
Tomado de: http://openejb.apache.org/3.0/testing-security-example.html
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
users.properties
bschuchert=password
msmith=password
dnunn=password
student=password
roles.properties
bschuchert=admin
msmith=admin
dnunn=admin
student=user
Tomado de: http://schuchert.wikispaces.com/EJB3+Tutorial+6+-+Security
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
@Stateless
@SecurityDomain("other")
public class AccountInventoryBean implements AccountInventory {
@PersistenceContext(unitName = "tolltag")
private EntityManager em;
public EntityManager getEm() {
return em;
}
/**
* Only allow users that can play the role of admin to access this method.
*/
@RolesAllowed( { "admin" })
public void createAccount(final Account account) {
getEm().persist(account);
}
@RolesAllowed( { "admin", "user" })
public Account findAccountById(final Long id) {
return getEm().find(Account.class, id);
}
Tomado de: http://schuchert.wikispaces.com/EJB3+Tutorial+6+-+Security
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
/**
* The default access is PermitAll if you do not otherwise specify the roles
* allowed. You can change this default by applying the RolesAllowed
* annotation to the class instead of a method.
*/
@PermitAll
public void removeTag(final String tagNumber) {
final TollTag tt = (TollTag) getEm().createNamedQuery(
"TollTag.byTollTagNumber").setParameter("tagNumber", tagNumber)
.getSingleResult();
final Account account = tt.getAccount();
account.removeTollTag(tt);
tt.setAccount(null);
getEm().remove(tt);
getEm().flush();
}
public void removeAccountById(final Long id) {
final Account toRemove = findAccountById(id);
getEm().remove(toRemove);
getEm().flush();
}
}
Tomado de: http://schuchert.wikispaces.com/EJB3+Tutorial+6+-+Security
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
public class AccountInventoryBeanTest {
private static final String WRONG_ACCOUNT = "this account does not exist";
private static final String WRONG_PASSWORD = "this is the wrong password";
private static final String USER_ACCOUNT = "student";
private static final String ADMIN_ACCOUNT = "bschuchert";
private static final String PASSWORD = "password";
@BeforeClass
public static void initContainer() {
JBossUtil.startDeployer();
}
public InitialContext getInitialContextFor(final String user,
final String password) throws NamingException {
final Properties p = new Properties();
p.setProperty(Context.SECURITY_PRINCIPAL, user);
p.setProperty(Context.SECURITY_CREDENTIALS, password);
p.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
return new InitialContext(p);
}
Tomado de: http://schuchert.wikispaces.com/EJB3+Tutorial+6+-+Security
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
public static TollTag instantiateTollTag() {
final TollTag tt = new TollTag();
tt.setTagNumber("1234567890");
return tt;
}
public static Vehicle instantiateVehicle() {
return new Vehicle("Subaru", "Outback", "2001", "YBU 155");
}
public static Account instantiateAccount() {
final Account account = new Account();
account.addTollTag(instantiateTollTag());
account.addVehicle(instantiateVehicle());
return account;
}
private void createAccountUsing(final String userName, final String password)
throws Exception {
final Account account = instantiateAccount();
final InitialContext ctx = getInitialContextFor(userName, password);
AccountInventory bean = (AccountInventory) ctx
.lookup("AccountInventoryBean/local");
bean.createAccount(account);
bean.removeAccountById(account.getId());
}
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
@Test
public void successfulCreateAccount() throws Exception {
createAccountUsing(ADMIN_ACCOUNT, PASSWORD);
}
@Test(expected = SecurityException.class)
public void unsuccessfulCreateAccountUserNotInRoll() throws Throwable {
try {
createAccountUsing(USER_ACCOUNT, PASSWORD);
} catch (EJBAccessException e) {
throw e.getCause();
}
}
@Test(expected = FailedLoginException.class)
public void unsuccessfulCreateAccountWrongPassowrd() throws Throwable {
try {
createAccountUsing(ADMIN_ACCOUNT, WRONG_PASSWORD);
} catch (Exception e) {
throw e.getCause();
}
}
Tomado de: http://schuchert.wikispaces.com/EJB3+Tutorial+6+-+Security
Pruebas Unitarias – EJB3
DEPARTAMENTO DE SISTEMAS
@Test(expected = FailedLoginException.class)
public void unsuccessfulCreateAccountWrongUser() throws Throwable {
try {
createAccountUsing(WRONG_ACCOUNT, PASSWORD);
} catch (Exception e) {
throw e.getCause();
}
}
@Test(expected = FailedLoginException.class)
public void unsuccessfulNoCredentials() throws Throwable {
try {
createAccountUsing("", "");
} catch (EJBAccessException e) {
throw e.getCause();
}
}
Tomado de: http://schuchert.wikispaces.com/EJB3+Tutorial+6+-+Security
Session Beans
DEPARTAMENTO DE SISTEMAS
•  Material preparado por
o 
o 
o 
56
María del Pilar Villamil
Nicolás López
Darío Correal
Referencias
DEPARTAMENTO DE SISTEMAS
[1] Rozanski N, Woods E. “Software Systems Architecture” AddisonWesley. 2005
[2] Documenting Component and Connector Views with UML 2.0,
Technical Report, ESC-TR-2004-08
[3] Gary McGraw. “Software Security – Building Security In” AddisonWesley. 2005
[4] Greg Hoglund, Gary McGraw, “Exploiting Software – How to Break
Code” Addison-Wesley, 2004
[5] ISO/IEC 15408-2:2005
57