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 asymmetric 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 asymmetric key that is identified by 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 X.509 certificate of the sender is embedded in the SAML security token. The sender signs selected parts of request message elements by using its corresponding private key and encrypts the request message by using the public key of the recipient. The recipient signs the selected elements of the response message by using the private key of the recipient, and encrypts selected elements of the response message by using the public key of the sender in SAML security tokens. The Web services security policy attached to the web services provider is provided for your reference.
- 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 the 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.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");The private key of the sender is specified by the SamlConstants.KEY_ALIAS property and is used to sign selected elements of the request message.
- 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.setTokenReference(SecurityToken.REF_KEYID); //If the gencon.add(samlToken); line of code is omitted, //the above line of code must be replaced with //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);In this example, encryption uses a 256 bit key size so import the Java Cryptography Extension (JCE) policy file. For more information, read about using the unrestricted JCE policy files in the "Tuning Web Services Security applications" topic.
- 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.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);- Use the JDK keytool utility to generate the saml-provider.jceks, initiator.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 storepass -keypass keypass -storetype jceks -validity 5000 -keyalg RSA -keysize 2048 keytool -genkey -alias soaprecipient -keystore recipient.jceks -dname "CN=SOAPRecipient, O=ACME" -storepass storepass -keypass keypass -storetype jceks -validity 5000 -keyalg RSA -keysize 2048 keytool -genkey -alias soapinitiator -keystore initiator.jceks -dname "CN=SOAPInitator, O=ACME" -storepass storepass -keypass keypass -storetype jceks -validity 5000 -keyalg RSA -keysize 2048 keytool -export -alias samlissuer -file issuerpub.cer -keystore saml-provider.jceks -storepass storepass -storetype jceks keytool -export -alias soaprecipient -file reciptpub.cer -keystore recipient.jceks -storepass storepass -storetype jceks keytool -export -alias soapinitiator -file initatpub.cer -keystore initiator.jceks -storepass storepass -storetype jceks keytool -import -alias samlissuer -file issuerpub.cer -keystore initiator.jceks -storepass storepass -storetype jceks -keypass keypass -noprompt keytool -import -alias soaprecipient -file reciptpub.cer -keystore initiator.jceks -storepass storepass -storetype jceks -keypass keypass -noprompt keytool -import -alias samlissuer -file issuerpub.cer -keystore recipient.jceks -storepass storepass -storetype jceks -keypass keypass -noprompt keytool -import -alias soapinitiator -file initatpub.cer -keystore recipient.jceks -storepass storepass -storetype jceks -keypass keypass -noprompt keytool -import -alias soapinitiator -file initatpub.cer -keystore saml-provider.jceks -storepass storepass -storetype jceks -keypass keypass -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 asymmetric key that is embedded in SAML security in message level protection.
Example
The following example illustrates the web services provider Web services security policy:<?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>
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 symmetric 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