Network Deployment (Distributed operating systems), v8.0 > Develop and deploying applications > Develop web services - Security (WS-Security) > Develop applications that use Web Services Security > Develop message-level security for JAX-WS web services > Secure web services applications using the WSS APIs at the message level > Secure messages at the request generator using WSS APIs > Secure messages at the request generator using WSS APIs
Send self-issued SAML holder-of-key tokens with symmetric key using WSS APIs
We can create self-issued SAML tokens with the holder-of-key subject confirmation method and then use the JAX-WS programming model and Web Services Security APIs (WSS APIs) to send these tokens with web services request messages.
This task assumes that you are familiar with the JAX-WS programming model, the WSS API interfaces, SAML concepts, and the use of policy sets to configure and administer web services settings. Complete the following actions before you begin this task:
This task focuses on using the symmetric key that is embedded in SAML security tokens to generate a digital signature of selected SOAP message elements in order to satisfy holder-of-key subject confirmation method security requirements. The Web Services Security policy attached to the web services provider is that of the SAML20 HoK Symmetric WSSecurity default policy set that is shipped in WAS 7.0.0.7 and later releases.
- Read about sending self-issued SAML bearer tokens by using WSS APIs.
- Read about sending self-issued SAML sender-vouches tokens by using WSS APIs with message level protection.
Procedure
- Create a SAML security token that contains holder-of-key subject confirmation method; for example:
WSSFactory factory = WSSFactory.getInstance(); // Initialize WSSGenerationContext com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext gencont = factory.newWSSGenerationContext(); // Initialize SAML issuer configuration via custom properties 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); //Add custom properties 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.SERVICE_ALIAS, "soaprecipient"); map.put(SamlConstants.KEY_TYPE, "http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey"); map.put(SamlConstants.SAML_APPLIES_TO, "http://localhost:9080/your_Web_service"); map.put(RequesterConfiguration.RSTT.ENCRYPTIONALGORITHM, "http://www.w3.org/2001/04/xmlenc#aes256-cbc"); map.put(SamlConstants.KEY_SIZE, "256"); SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map); SAMLToken samlToken = (SAMLToken) factory.newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml");The embedded proof key in the SAML security token is encrypted for the target Web service. The public key of the target service that encrypts the proof key is specified by the SamlConstants.SERVICE_ALIAS property which specifies a public certificate in the trust file. The trust file location is specified by a com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext custom property. In this example, import the Java Cryptography Extension (JCE) policy file because encryption uses 256 bit key size. For more information, read about using the unrestricted JCE policy files in the "Tuning Web Services Security applications" topic.
If you prefer to use derived keys for digital signing and for encryption instead of using symmetric key directly, add the following name-value pair:
map.put(SamlConstants.REQUIRE_DKT, "true");- Use the WSSGenerationContext object to prepare for request message security header processing; for example:
gencon.add(samlToken); //this line of code can be omitted WSSTimestamp timestamp = factory.newWSSTimestamp(); gencon.add(timestamp); WSSSignature sig = factory.newWSSSignature(samlToken); sig.setSignatureMethod(WSSSignature.HMAC_SHA1); sig.setCanonicalizationMethod(WSSSignature.EXC_C14N); sig.addSignPart(WSSSignature.BODY); sig.addSignPart(WSSSignature.TIMESTAMP); sig.addSignPart(WSSSignature.ADDRESSING_HEADERS); sig.setTokenReference(SecurityToken.REF_KEYID); //If the gencon.add(samlToken); line of code is omitted, or DerivedKey is used //the above line of code must be replaced with //sig.setTokenReference(SecurityToken.REF_STR); gencon.add(sig); WSSEncryption enc = factory.newWSSEncryption(samlToken); enc.setEncryptionMethod(WSSEncryption.AES256); enc.setTokenReference(SecurityToken.REF_KEYID); //If the gencon.add(samlToken); line of code is omitted, or DerivedKey is used //the above line of code must be replaced with //enc.setTokenReference(SecurityToken.REF_STR); enc.encryptKey(false); enc.addEncryptPart(WSSEncryption.BODY_CONTENT); enc.addEncryptPart(WSSEncryption.SIGNATURE); gencon.add(enc);
- Create the WSSConsumingContext object to prepare for response message, security header processing; for example:
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.encryptKey(false); dec.addRequiredDecryptPart(WSSDecryption.BODY_CONTENT); concont.add(dec); callbackHandler = new SAMLConsumerCallbackHandler(map); WSSVerification ver = factory.newWSSVerification(SAMLToken.class, callbackHandler, "system.wss.consume.saml"); ver.addAllowedSignatureMethod(WSSVerification.HMAC_SHA1); ver.addRequiredVerifyPart(WSSVerification.BODY); ver.addRequiredVerifyPart(WSSVerification.TIMESTAMP); concont.add(ver);- Use the JDK keytool utility to generate the saml-provider.jceks and recipient.jceksfiles that are used to test the example code; for example:
keytool -genkey -alias samlissuer -keystore saml-provider.jceks -dname "CN=SAMLIssuer, O=ACME" -storepass issuerstorepass -keypass issuerkeypass -storetype jceks -validity 5000 -keyalg RSA -keysize 2048 keytool -genkey -alias soaprecipient -keystore recipient.jceks -dname "CN=SOAPRecipient, O=ACME" -storepass reciptstorepass -keypass reciptkeypass -storetype jceks -validity 5000 -keyalg RSA -keysize 2048 keytool -export -alias soaprecipient -file reciptpub.cer -keystore recipient.jceks -storepass reciptstorepass -storetype jceks keytool -import -alias soaprecipient -file reciptpub.cer -keystore saml-provider.jceks -storepass issuerstorepass -storetype jceks -keypass issuerkeypass -noprompt
Results
You have learned key building blocks to create a web services client application to send a SAML security token in a SOAP message and to use the symmetric key that is embedded in SAML security in message level protection.
SAML concepts
Configure client and provider bindings for the SAML bearer token
Send self-issued SAML bearer tokens using WSS APIs
Send self-issued SAML holder-of-key tokens with asymmetric key using WSS APIs
Tune Web Services Security for v8.0 applications
Manage self-issue SAML token configuration using wsadmin
Related
Web Services Security APIs