Puede crear señales SAML autoemitidas con el método de confirmación de sujetos holder-of-key y, a continuación, utilizar la API
de Java™ para servicios web XML (JAX-WS) y las API de seguridad de servicios web (WSS) para enviar esas señales con mensajes de solicitud de servicios web.
Antes de empezar
En esta tarea se presupone que está familiarizado con el modelo
de programación JAX-WS, las interfaces de las API de WSS, los conceptos de SAML
y el uso de conjuntos de políticas para configurar y administrar los valores
de servicios web.
Complete las acciones siguientes antes de iniciar esta tarea:
- Consulte información sobre el envío de señales bearer SAML autoemitidas
mediante las API de WSS.
- Consulte información sobre el envío de señales sender-vouches SAML autoemitidas
mediante las API de WSS con protección a nivel de mensaje.
Acerca de esta tarea
Esta tarea se centra en el uso de la clave asimétrica identificada por las señales
de seguridad SAML para generar una firma digital de elementos message SOAP seleccionados con el fin
de satisfacer los requisitos de seguridad del método de confirmación de sujetos holder-of-key.
El certificado X.509 del emisor está incluido en la señal de seguridad SAML.
El emisor firma las partes de los elementos del mensaje de solicitud seleccionadas
utilizando su clave privada correspondiente y cifra el mensaje de solicitud
mediante la clave pública del destinatario. El destinatario firma los elementos seleccionados
del mensaje de respuesta utilizando la clave privada del destinatario y cifra los elementos
seleccionados del mensaje de respuesta utilizando la clave pública del emisor de señales de
seguridad SAML. Se facilita la política de seguridad de servicios Web conectada al proveedor
de servicios web a modo de referencia.
Procedimiento
- Cree una señal de seguridad SAML que contiene el método de confirmación de sujetos holder-of-key; por ejemplo:
WSSFactory factory = WSSFactory.getInstance();
// Inicializar WSSGenerationContext
com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext gencont = factory.newWSSGenerationContext();
// Inicializar la configuración del emisor de SAML mediante propiedades personalizadas
HashMap<Object, Object> customProps = new HashMap<Object,Object>();
customProps.put(SamlConstants.ISSUER_URI_PROP, "example.com");
customProps.put(SamlConstants.TTL_PROP, "3600000");
customProps.put(SamlConstants.KS_PATH_PROP, "keystores/saml-provider.jceks");
customProps.put(SamlConstants.KS_TYPE_PROP, "JCEKS");
customProps.put(SamlConstants.KS_PW_PROP, "{xor}LCswLTovPiws");
customProps.put(SamlConstants.KEY_ALIAS_PROP, "samlissuer");
customProps.put(SamlConstants.KEY_NAME_PROP, "CN=SAMLIssuer, O=EXAMPLE");
customProps.put(SamlConstants.KEY_PW_PROP, "{xor}NDomLz4sLA==");
customProps.put(SamlConstants.TS_PATH_PROP, "keystores/saml-provider.jceks");
customProps.put(SamlConstants.TS_TYPE_PROP, "JCEKS");
customProps.put(SamlConstants.TS_PW_PROP, "{xor}LCswLTovPiws");
gencont.add(customProps); //Añadir propiedades personalizadas
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put(SamlConstants.CONFIRMATION_METHOD, "holder-of-key");
map.put(SamlConstants.Token_REQUEST, "issue");
map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
map.put(SamlConstants.SIGNATURE_REQUIRED, "true");
map.put(SamlConstants.KEY_TYPE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey");
map.put(SamlConstants.SAML_APPLIES_TO, "http://localhost:9080/your_Web_service");
map.put(SamlConstants.KEY_ALIAS, "soapinitiator" );
map.put(SamlConstants.KEY_NAME, "CN=SOAPInitator, O=ACME");
map.put(SamlConstants.KEY_PASSWORD, "keypass");
map.put(SamlConstants.KEY_STORE_PATH, "keystores/initiator.jceks");
map.put(SamlConstants.KEY_STORE_PASSWORD, "storepass");
map.put(SamlConstants.KEY_STORE_TYPE, "jceks");
SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);
SAMLToken samlToken = (SAMLToken) factory.newSecurityToken(SAMLToken.class,
callbackHandler, "system.wss.generate.saml");
La clave privada del emisor se especifica mediante la propiedad SamlConstants.KEY_ALIAS
y se utiliza para firmar los elementos seleccionados del mensaje de solicitud.
- Utilice el objeto WSSGenerationContext para prepararse para el proceso de cabeceras
de seguridad de mensajes de solicitud; por ejemplo:
gencon.add(samlToken); //esta línea de código se puede omitir WSSTimestamp timestamp = factory.newWSSTimestamp();
gencon.add(timestamp);
WSSSignature sig = factory.newWSSSignature(samlToken);
sig.setTokenReference(SecurityToken.REF_KEYID);
//Si se omite la línea de código gencon.add(samlToken);,
//la línea anterior de código se debe sustituir por
//sig.setTokenReference(SecurityToken.REF_STR);
sig.setSignatureMethod(WSSSignature.RSA_SHA1);
sig.setCanonicalizationMethod(WSSSignature.EXC_C14N);
sig.addSignPart(WSSSignature.BODY);
sig.addSignPart(WSSSignature.TIMESTAMP);
sig.addSignPart(WSSSignature.ADDRESSING_HEADERS);
gencon.add(sig);
X509GenerateCallbackHandler x509callbackHandler2 = new X509GenerateCallbackHandler(
null,
"keystores/initiator.jceks",
"jceks",
"storepass".toCharArray(),
"soaprecipient",
null,
"", null);
SecurityToken st2 = factory.newSecurityToken(X509Token.class, x509callbackHandler2);
WSSEncryption enc = factory.newWSSEncryption(st2);
enc.addEncryptPart(WSSEncryption.BODY_CONTENT);
enc.addEncryptPart(WSSEncryption.SIGNATURE);
enc.setEncryptionMethod(WSSEncryption.AES256);
enc.setKeyEncryptionMethod(WSSEncryption.KW_RSA_OAEP);
gencon.add(enc);
En este ejemplo, el cifrado utiliza un tamaño de clave de 256 bits por lo que debe importar
el archivo de políticas JCE (Java Cryptography Extension).
Para obtener más información, consulte al apartado sobre utilización de archivos de políticas JCE sin restricciones
del tema "Ajuste de aplicaciones de seguridad de servicios web".
- Cree el objeto WSSConsumingContext para prepararse para el proceso
de cabeceras de seguridad del mensaje de respuesta; por ejemplo:
WSSConsumingContext concont = factory.newWSSConsumingContext();
HashMap<Object, Object> map = new HashMap<Object, Object>();
SAMLConsumerCallbackHandler callbackHandler = new SAMLConsumerCallbackHandler(map);
WSSDecryption dec = factory.newWSSDecryption(SAMLToken.class, callbackHandler,
"system.wss.consume.saml");
dec.addAllowedEncryptionMethod(WSSDecryption.AES256);
dec.addAllowedKeyEncryptionMethod(WSSDecryption.KW_RSA_OAEP);
dec.encryptKey(false);
dec.addRequiredDecryptPart(WSSDecryption.BODY_CONTENT);
concont.add(dec);
X509ConsumeCallbackHandler verHandler = new X509ConsumeCallbackHandler(null,
"keystores/initiator.jceks",
"jceks",
"storepass".toCharArray(),
"soaprecipient",
null, null);
WSSVerification ver = factory.newWSSVerification(X509Token.class, verHandler);
ver.addRequiredVerifyPart(WSSVerification.BODY);
concont.add(ver);
- Utilice el programa de utilidad keytool de JDK para generar los archivos saml-provider.jceks,
initiator.jceks y recipient.jceks que se utilizan para probar el código de ejemplo; por ejemplo:
keytool -genkey -alias samlissuer -keystore saml-provider.jceks -dname "CN=SAMLIssuer, O=ACME" -storepass myissuerstorepass -keypass myissuerkeypass
-storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -genkey -alias soaprecipient -keystore recipient.jceks -dname "CN=SOAPRecipient, O=ACME" -storepass myreciptstorepass -keypass myreciptkeypass
-storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -genkey -alias soapinitiator -keystore initiator.jceks -dname "CN=SOAPInitator, O=ACME" -storepass myinitatstorepass -keypass myinitatkeypass
-storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -export -alias samlissuer -file issuerpub.cer -keystore saml-provider.jceks -storepass myissuerstorepass -storetype jceks
keytool -export -alias soaprecipient -file reciptpub.cer -keystore recipient.jceks -storepass myreciptstorepass -storetype jceks
keytool -export -alias soapinitiator -file initatpub.cer -keystore initiator.jceks -storepass myinitatstorepass -storetype jceks
keytool -import -alias samlissuer -file issuerpub.cer -keystore initiator.jceks -storepass myissuerstorepass -storetype jceks -keypass myissuerkeypass -noprompt
keytool -import -alias soaprecipient -file reciptpub.cer -keystore initiator.jceks -storepass myreciptstorepass -storetype jceks -keypass myreciptkeypass -noprompt
keytool -import -alias samlissuer -file issuerpub.cer -keystore recipient.jceks -storepass myreciptstorepass -storetype jceks -keypass myreciptkeypass -noprompt
keytool -import -alias soapinitiator -file initatpub.cer -keystore initiator.jceks -storepass myinitatstorepass -storetype jceks -keypass myinitatkeypass -noprompt
keytool -import -alias soapinitiator -file initatpub.cer -keystore saml-provider.jceks -storepass myissuerstorepass -storetype jceks -keypass myissuerkeypass -noprompt
Resultados
Ha obtenido información sobre bloques de creación clave para crear una aplicación cliente de servicios web con el fin de enviar una señal de seguridad SAML en un mensaje SOAP y para utilizar la clave asimétrica que está incluida en la seguridad SAML de protección a nivel de mensaje.
Ejemplo
En el ejemplo siguiente se ilustra la política de seguridad de servicios Web del proveedor de servicios web:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:spe="http://www.ibm.com/xmlns/prod/websphere/200605/ws-securitypolicy-ext">
<wsp:Policy wsu:Id="response:app_encparts">
<sp:EncryptedElements>
<sp:XPath>/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Envelope']/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature']</sp:XPath>
<sp:XPath>/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Envelope']/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature']</sp:XPath>
</sp:EncryptedElements>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:Policy>
<wsp:Policy wsu:Id="request:req_enc">
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:Policy>
<wsp:Policy wsu:Id="request:app_signparts">
<sp:SignedParts>
<sp:Body/>
<sp:Header Namespace="http://schemas.xmlsoap.org/ws/2004/08/addressing"/>
<sp:Header Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:SignedElements>
<sp:XPath>/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Envelope']/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
and local-name()='Timestamp']</sp:XPath>
<sp:XPath>/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Envelope']/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
and local-name()='Timestamp']</sp:XPath>
</sp:SignedElements>
</wsp:Policy>
<wsp:Policy wsu:Id="response:resp_sig">
<sp:SignedParts>
<sp:Body/>
</sp:SignedParts>
</wsp:Policy>
<sp:AsymmetricBinding>
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<spe:CustomToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512/IncludeToken/Always"/>
<wsp:Policy>
<spe:WssCustomToken localname="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"/>
</wsp:Policy>
</spe:CustomToken>
</wsp:Policy>
</sp:InitiatorToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:IncludeTimestamp/>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512/IncludeToken/Always"/>
<wsp:Policy>
<sp:WssX509V3Token11/>
</wsp:Policy>
</sp:X509Token>
<wsp:Policy>
<sp:RecipientToken>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<wsp:Policy>
<sp:AsymmetricBinding>
</wsp:Policy>