Ejemplo: Implementación de com.ibm.wsspi.security.token.PropagationToken
Utilice este archivo para ver un ejemplo de una implementación de señal de propagación. El código de ejemplo siguiente no amplía una clase abstracta sino que implementa directamente la interfaz com.ibm.wsspi.security.token.PropagationToken. Puede implementar directamente la interfaz pero es posible que tenga que escribir dos veces el código. No obstante, puede optar por implementar directamente la interfaz si hay alguna diferencia importante en el modo en que maneja las diferentes implementaciones de las señales.
Para obtener información acerca de cómo implementar una señal de propagación personalizada, consulte Implementación de una señal de propagación personalizada para la propagación de atributos de seguridad.
package com.ibm.websphere.security.token;
import com.ibm.websphere.security.WSSecurityException;
import com.ibm.websphere.security.auth.WSLoginFailedException;
import com.ibm.wsspi.security.token.*;
import com.ibm.websphere.security.WebSphereRuntimePermission;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.util.ArrayList;
public class CustomPropagationTokenImpl implements com.ibm.wsspi.security.
token.PropagationToken
{
private java.util.Hashtable hashtable = new java.util.Hashtable();
private byte[] tokenBytes = null;
// 2 horas en miliseg., de forma predeterminada
private static long expire_period_in_millis = 2*60*60*1000;
private long counter = 0;
/**
* El constructor utilizado para crear la instancia inicial de PropagationToken
*/
public CustomAbstractTokenImpl ()
{
// establece la versión de la señal
addAttribute("version", "1");
// Establece la caducidad de la señal
addAttribute("expiration", new Long(System.currentTimeMillis() +
expire_period_in_millis).toString());
}
/**
* El constructor utilizado para deserializar los bytes de señal recibidos
* durante un inicio de sesión de propagación.
*/
public CustomAbstractTokenImpl (byte[] token_bytes)
{
try
{
hashtable = (java.util.Hashtable) com.ibm.wsspi.security.token.
WSOpaqueTokenHelper.deserialize(token_bytes);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* Valida la señal incluidos la caducidad, la firma, etc.
* @return boolean
*/
public boolean isValid ()
{
long expiration = getExpiration();
// Si establece la caducidad en 0, la señal no caduca
if (expiration != 0)
{
// devolver si esta señal continúa siendo válido
long current_time = System.currentTimeMillis();
boolean valid = ((current_time < expiration) ? true : false);
System.out.println("isValid: returning " + valid);
return valid;
}
else
{
System.out.println("isValid: returning true by default");
return true;
}
}
/**
* Obtiene la caducidad como un tipo long.
* @return long
*/
public long getExpiration()
{
// Obtiene el valor de caducidad de la tabla de totales de control
String[] expiration = getAttributes("expiration");
if (expiration != null && expiration[0] != null)
{
// La caducidad es el primer elemento y solo debe haber una caducidad
System.out.println("getExpiration: returning " + expiration[0]);
return new Long(expiration[0]).longValue();
}
System.out.println("getExpiration: returning 0");
return 0;
}
/**
* Indica si esta señal debe reenviarse o propagarse en sentido descendente.
* @return boolean
*/
public boolean isForwardable()
{
// Puede seleccionar si la señal se ha de propagar. En algunos casos,
// quizá prefiera que la señal sea sólo local.
return true;
}
/**
* Obtiene el principal al que pertenece esta señal. Si este es una
* señal de autorización, la serie de principal debe coincidir con
* la serie de principal de la señal de autenticación o se rechazará el mensaje.
* @return String
*/
public String getPrincipal()
{
// No es necesario que PropagationToken devuelva un principal,
// porque no está centrado en el usuario.
return "";
}
/**
* Devuelve un identificador exclusivo de la señal basándose en la información
* que el proveedor cree que lo convierte en señal exclusiva. Este identificador
* se usa con fines de almacenamiento en memoria caché y se puede utilizar junto con otros
* ID exclusivos de señales que son parte del mismo Subject.
*
* Este método debe devolver un valor nulo si desea que el accessID del usuario
* represente su carácter exclusivo. Este es el escenario típico.
*
* @return String
*/
public String getUniqueID()
{
// Si desea propagar los cambios de esta señal, cambie el valor
// que devuelve este ID exclusivo siempre que se modifique la señal.
// De lo contrario, CSIv2 utiliza una sesión existente cuando todo lo
// demás es igual. CSIv2 comprueba este getUniqueID para determinar
// la consulta de sesión.
return counter;
}
/**
* Obtiene los bytes que se enviarán a través de las comunicaciones. byte[] debe incluir la
* información necesaria para volver a crear el objeto de señal en el servidor de destino.
* @return byte[]
*/
public byte[] getBytes ()
{
if (hashtable != null)
{
try
{
// Haga lo siguiente si el objeto es de sólo lectura durante la confirmación de
// conexión ya que de este modo se asegura de que no se establezcan datos nuevos.
if (isReadOnly() && tokenBytes == null)
tokenBytes = com.ibm.wsspi.security.token.WSOpaqueTokenHelper.
serialize(hashtable);
// Puede deserializarlo en el módulo de conexión en sentido descendente utilizando
// WSOpaqueTokenHelper.deserialize()
return tokenBytes;
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
System.out.println("getBytes: returning null");
return null;
}
/**
* Obtiene el nombre de la señal, que se utiliza para identificar byte[] en el
* mensaje de protocolo.
* @return String
*/
public String getName()
{
return this.getClass().getName();
}
/**
* Obtiene la versión de la señal como un tipo short. Este código se utiliza también
* para identificar byte[] en el mensaje de protocolo.
* @return short
*/
public short getVersion()
{
String[] version = getAttributes("version");
if (version != null && version[0] != null)
return new Short(version[0]).shortValue();
System.out.println("getVersion: returning default of 1");
return 1;
}
/**
* Cuando se llama, la señal pasa a ser de sólo lectura de forma irreversible. La
* implementación ha de asegurarse de que los métodos setter comprueben que se
* ha establecido este distintivo de sólo lectura.
*/
public void setReadOnly()
{
addAttribute("readonly", "true");
}
/**
* Se llama internamente para ver si la señal es de sólo lectura
*/
private boolean isReadOnly()
{
String[] readonly = getAttributes("readonly");
if (readonly != null && readonly[0] != null)
return new Boolean(readonly[0]).booleanValue();
System.out.println("isReadOnly: returning default of false");
return false;
}
/**
* Obtiene el valor del atributo basándose en el valor nombrado.
* @param String key
* @return String[]
*/
public String[] getAttributes(String key)
{
ArrayList array = (ArrayList) hashtable.get(key);
if (array != null && array.size() > 0)
{
return (String[]) array.toArray(new String[0]);
}
return null;
}
/**
* Obtiene el par nombre-valor del atributo. Devuelve los valores de key ya establecidos
* o devuelve un valor nulo si no se ha establecido anteriormente.
* @param String key
* @param String value
* @returns String[];
*/
public String[] addAttribute(String key, String value)
{
// Obtiene el valor actual para key
ArrayList array = (ArrayList) hashtable.get(key);
if (!isReadOnly())
{
// Aumenta el contador para cambiar uniqueID
counter++;
// Copia ArrayList en String[] como existe actualmente
String[] old_array = null;
if (array != null && array.size() > 0)
old_array = (String[]) array.toArray(new String[0]);
// Asigna una ArrayList nueva si no se ha encontrado una
if (array == null)
array = new ArrayList();
// Añade la serie a la lista de matrices actual
array.add(value);
// Añade la ArrayList actual a la tabla de totales de control
hashtable.put(key, array);
// Devuelve la matriz antigua
return old_array;
}
return (String[]) array.toArray(new String[0]);
}
/**
* Obtiene la lista de todos los nombres de atributos existentes en la señal.
* @return java.util.Enumeration
*/
public java.util.Enumeration getAttributeNames()
{
return hashtable.keys();
}
/**
* Devuelve un clon exacto de esta señal. Esto se utiliza habitualmente por parte
* de la lógica de sesión del servidor CSIv2 para crear una copia de la señal como
* existe en la sesión.
* @return Object
*/
public Object clone()
{
com.ibm.websphere.security.token.CustomPropagationTokenImpl deep_clone =
new com.ibm.websphere.security.token.CustomPropagationTokenImpl();
java.util.Enumeration keys = getAttributeNames();
while (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
String[] list = (String[]) getAttributes(key);
for (int i=0; i<list.length; i++)
deep_clone.addAttribute(key, list[i]);
}
return deep_clone;
}
}