+

Search Tips   |   Advanced Search

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 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 we 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 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 WebSphere Application Server 7.0.0.7 and later releases.

  1. Create a SAML security token containing 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, we must import the Java Cryptography Extension (JCE) policy file because encryption uses 256 bit key size. See using the unrestricted JCE policy files in the "Tuning Web Services Security applications" topic.

    If we 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");

  2. 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);

  3. 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);

  4. Use the JDK keytool utility to generate the saml-provider.jceks and recipient.jceksfiles 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 embedded in SAML security in message level protection.


Related concepts

  • SAML concepts


    Related tasks

  • 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.5 applications
  • Manage self-issue SAML token configuration using wsadmin commands

  • Web Services Security APIs