Puede utilizar las SPI GenericSecurityTokenFactory para crear señales X.509 para que las utilice el entorno de ejecución de WS-Security. Estas señales de seguridad se pueden utilizar, pero no están limitadas a ello, para módulos de inicio de sesión JAAS y WSSAPIs.
Acerca de esta tarea
Cuando se utiliza una SPI GenericSecurityTokenFactory para crear una señal X.509 que no contenga XML, la señal sólo la puede emitir el generador X.509 y consumir el consumidor X.509. Por lo tanto, una señal X.509 está considerada como una señal simple, la cual sólo está diseñada para ser utilizada por su respectivo consumidor o generador específico de señales. Una señal
X.509 no puede ser emitida por el GenericSecurityTokenLoginModule.
El GenericSecurityTokenFactory proporciona varias SPI que puede utilizar para crear señales X.509 que se pueden emitir con X509GenerateLoginModule
o consumidas por X509ConsumeLoginModule. Las señales X.509 creadas utilizando una SPI GenericSecurityTokenFactory contienen claves públicas y/o privadas que se pueden utilizar para firmar o cifrar un mensaje de salida o descifrar y verificar la firma de un mensaje de entrada.
Es recomendable que utilice este tipo de señal:
- Si necesita cambiar de forma dinámica la clave de firma para un mensaje.
Por ejemplo, X509GenerateCallbackHandler requiere que la clave de firma esté codificada en el momento de la configuración. Si debe alterar temporalmente este valor codificado, puede codificar un módulo de inicio de sesión JAAS que esté apilado sobre X509GenerateLoginModule de modo que el módulo de inicio de sesión coloque una simple señal
X.509 en el estado compartido. X509GenerateLoginModule utiliza la clave privada que está especificada en la señal simple X.509 para alterar temporalmente la que está configurada en el manejador de devolución de llamada.
- Si debe permitir que varias firmas verifiquen certificados que no aparecen en el mensaje SOAP. Estos mensajes incluirían los certificados a los que hacen referencia los atributos como KEYID y X509IssuerSerial. El motor WS-Security no resuelve de forma dinámica certificados que no aparecen en el mensaje SOAP. El certificado debe codificarse en el X509ConsumeCallbackHandler y sólo puede configurar un certificado en el manejador de devolución de llamada. Si decide implementar código que resuelve el certificado usted mismo, puede colocar estos códigos en un módulo de inicio de sesión JAAS apilado en X509ConsumeLoginModule y, a continuación, colocar una señal X.509 simple en el estado compartido que contiene el certificado público deseado.
X509ConsumeLoginModule utiliza el certificado público especificado en la señal simple X.509 para alterar temporalmente la que está configurada en el manejador de devolución de llamada.
Una vez creada una señal X.509, las claves pública y privada de la señal no pueden modificarse. Por lo tanto, debe determinar el tipo de señal que desea crear y luego emitir mandatos similares a los especificados en los pasos siguientes para crear una señal y un módulo de inicio de sesión JAAS.
- Crear una señal X.509 simple
Decida el tipo de señal X.509 simple que desea crear y emita mandatos similares a los de las siguientes series de mandatos.
- Crear una señal X.509 simple con un certificado público.
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.token.X509Token;
import java.security.cert.X509Certificate;
...
X509Certificate publicCert = null;
GenericSecurityTokenFactory factory = GenericSecurityTokenFactory.getInstance();
//implementar código para obtener el certificado público
X509Token x509 = factory.getSimpleX509PublicToken(publicCert);
- Crear una señal X.509 simple con una clave privada y opcional.
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.token.X509Token;
import java.security.Key;
import java.security.cert.X509Certificate;
...
Key privateKey = null;
X509Certificate publicCert = null;
GenericSecurityTokenFactory factory = GenericSecurityTokenFactory.getInstance();
//implementar código para obtener clave privada
//implementar código opcionalmente para obtener el certificado público
X509Token x509 = null;
try {
x509 = factory.getSimpleX509PrivateToken(publicCert , privateKey);
} catch (WSSException ex) {
//lanza una excepción si privateKey es null
}
- Cree un módulo de inicio de sesión JAAS que puede apilarse encima de
X509GenerateLoginModule o X509ConsumeLoginModule.
package test.tokens;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSUtilFactory;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import com.ibm.websphere.wssecurity.wssapi.token.X509Token;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
public class MyX509LoginModule implements LoginModule {
//Para facilitar la comprensión, este módulo de inicio de sesión no
//protege contra todos los NPE
private Map _sharedState;
private Map _options;
private CallbackHandler _handler;
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this._handler = callbackHandler;
this._sharedState = sharedState;
this._options = options;
}
public boolean login() throws LoginException {
GenericSecurityTokenFactory factory = null;
WSSUtilFactory utilFactory = null;
try {
factory = GenericSecurityTokenFactory.getInstance();
utilFactory = WSSUtilFactory.getInstance();
} catch(Exception e) {
throw new LoginException(e.toString());
}
X509Token x509 = null;
try {
x509 = getX509Token(factory, utilFactory);
} catch(Exception e) {
throw new LoginException("Exception: "+e.toString());
}
//si se genera (signing/encrypting):
factory.putGeneratorTokenToSharedState(this._sharedState, x509);
//Si se consume (decrypting/signature verification):
factory.putConsumerTokenToSharedState(this._sharedState, x509);
return true;
}
public X509Token getX509Token (GenericSecurityTokenFactory factory,
WSSUtilFactory utilFactory) throws Exception{
//Este ejemplo utiliza un almacén de claves de ejemplo
final String KEYSTORE = "c:/WebSphere/AppServer/profiles/AppSrv01/etc/ws-security/samples/dsig-sender.ks";
final String KEYSTORE_PASS = "client";
final String ALIAS = "soaprequester";
final String ALIAS_PASS = "client";
final String KEYSTORE_TYPE = "jks";
X509Certificate publicKey = null;
java.security.Key privateKey = null;
java.security.cert.Certificate cert = null;
X509Token x509 = null;
//Si debe obtener una señal de entrada para que pueda realizar procedimientos
//para determinar el certificado que se debe obtener, obtenga OMElement para la señal de entrada
Map wssContext = utilFactory.GetWSSContext(this._handler);
org.apache.axiom.om.OMElement element = utilFactory.getProcessingElement(wssContext);
//Abra el almacén de claves
java.security.KeyStore keystore = utilFactory.getKeyStore(KEYSTORE_TYPE, KEYSTORE, KEYSTORE_PASS.toCharArray());
//Obtenga la entrada del almacén de claves
KeyStore.PasswordProtection pwdProtection = null;
if (ALIAS_PASS != null) {
pwdProtection = new KeyStore.PasswordProtection(ALIAS_PASS.toCharArray());
}
KeyStore.Entry entry = keystore.getEntry(ALIAS, pwdProtection);
//Obtenga la clave pública o privada de la entrada
si (entry instanceof KeyStore.PrivateKeyEntry) {
//la entrada es una clave privada
KeyStore.PrivateKeyEntry pkentry = (KeyStore.PrivateKeyEntry)entry;
cert = pkentry.getCertificate();
privateKey = pkentry.getPrivateKey();
} else if (entry instanceof KeyStore.TrustedCertificateEntry) {
//la entrada es una clave pública
KeyStore.TrustedCertificateEntry tcentry = (KeyStore.TrustedCertificateEntry)entry;
cert = tcentry.getTrustedCertificate();
}
if ((cert != null) && (cert instanceof X509Certificate)) {
publicKey = (X509Certificate)cert;
} else {
throw new LoginException("Certificate is not X509Certificate");
}
x509 = factory.getSimpleX509Token(publicKey, privateKey);
if (x509 == null) {
throw new LoginException("X509Token is null");
}
return x509;
}
}
- Crear una configuración de inicio de sesión JAAS.
Nota: En este paso se presupone que está apilando en X509GenerateLoginModule
para generar una señal. Si desea apilar en X509ConsumeLoginModule para consumir una señal, debe ajustar los pasos para acomodar esta variación.
- En la consola administrativa, vaya a .
- En autenticación, vaya a .
- Pulse Nuevo y en Alias especifique test.generate.x509.
- En los módulos de inicio de sesión JAAS, pulse Nuevo y bajo el nombre de clase de módulo especifique test.tokens.MyX509LoginModule.
Seleccione Utilizar proxy de módulo de inicio de sesión y pulse Aceptar.
- Pulse Nuevo y bajo el nombre de clase de módulo especifique com.ibm.ws.wssecurity.wssapi.token.impl.X509GenerateLoginModule.
Pulse Aceptar.
- Pulse JAAS - Inicios de sesión de sistema en los rastros de navegación para volver a
la página de inicios de sesión del sistema JAAS.
- Configure el generador de señales X.509 para utilizar la nueva configuración JAAS.
Nota: En este paso se presupone que está apilando en X509GenerateLoginModule
para generar una señal. Si desea apilar en X509ConsumeLoginModule para consumir una señal, debe ajustar los pasos para acomodar esta variación.
- En la consola administrativa, abra la configuración de enlaces que desea cambiar.
- Seleccione .
- Bajo las señales de autenticación, seleccione la señal X.509 que desea cambiar.
- Bajo el inicio de sesión JAAS, seleccione test.generate.x509.
- Pulse Aceptar, luego Guardar.
- Reinicie el servidor de aplicaciones para aplicar los cambios de configuración JAAS.
- Pruebe el servicio.