Adding attributes and re-signing existing SAML tokens by using the API

The SAML library API can be used to add attributes to or delete attributes from a SAML token that is not encrypted, then sign, or re-sign the SAML token. Whenever any actions are made to modify the SAML token object, if a digital signature already exists on the object, the existing digital signature is removed.

About this task

The following procedure describes how to modify an existing SAMLToken object, then apply a new digital signature to the token. This task does not show how to obtain the existing SAMLToken object. The existing SAMLToken object can come from an inbound SOAP by way of the LoginModule shared state, SAML web SSO by way of the base Security Subject, an STS that uses the trust client, or a self-issued token that is created with the SAML APIs.

When the SAML APIs initialize configuration objects, the configuration is obtained from SamlIssuerConfig.properties. You can choose to use the settings in SamlIssuerConfig.properties or override them. This procedure shows how to override all the settings in this file.

Procedure

  1. Clone the existing SAML token
    import java.util.ArrayList;
    import org.apache.axiom.om.OMElement;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
    import com.ibm.wsspi.wssecurity.saml.config.ProviderConfig;
    import com.ibm.wsspi.wssecurity.saml.config.RequesterConfig;
    import com.ibm.wsspi.wssecurity.saml.data.SAMLAttribute;
    import com.ibm.wsspi.wssecurity.wssapi.OMStructure;
    ....
    
    //someSAMLToken is the existing SAMLToken object
    
    SAMLTokenFactory samlFactory = null;
    
    //initialize the desired SAML token factory
    //samlFactory = SAMLTokenFactory.getInstance(SAMLTokenFactory.WssSamlV11Token11);
    samlFactory = SAMLTokenFactory.getInstance(SAMLTokenFactory.WssSamlV20Token11);
    
    //clone the existing SAMLToken object if desired.
    SAMLToken mySamlToken = factory.newSAMLToken(someSamlToken);
  2. Add attributes to or delete attributes from the token
    //add a single attribute
    SAMLAttribute sattribute1 = new SAMLAttribute("Purchases", new String[] {"TooMany"},  null, null, null, null);
    mySamlToken.addAttribute(sattribute1);
    
    //after this first addAttribute, there will not be a digital signature in the
    //token's XML.  Doing a token modification invalidated the signature.
    
    //add a list of attributes
    SAMLAttribute sattribute2 = new SAMLAttribute("Address", new String[] {"Austin, Texas"},null,null,"IBM NameFormat","IBM FriendlyName");
    SAMLAttribute sattribute3 = new SAMLAttribute("Membership",new String[] {"Blue team", "Green Team"},null,null,null,null );
    
    ArrayList al = new ArrayList();
    al.add(sattribute2);
    al.add(sattribute3);
    
    mySamlToken.addAttribute(al);
    
    //delete an attribute
    mySamlToken.deleteAttribute(sattribute3);
    ....
  3. Re-sign the SAML token.
    RequesterConfig reqData = null;
    
    //initialize the desired requester config
    //reqData = samlFactory.newSenderVouchesTokenGenerateConfig();
    reqData = samlFactory.newBearerTokenGenerateConfig();
    
    //initialize the provider config object with an issuer name
    ProviderConfig samlIssuerCfg = samlFactory.newDefaultProviderConfig("myIssuer");
    
    //Or preserve the existing issuer by setting the issuer URI to null
    //samlIssuerCfg.setIssuerURI(null);
    
    //set the keystore information for use with digital signature in the provider config object
    KeyStoreConfig ksc = samlFactory.newKeyStoreConfig( "jks", "/myx509.ks", "myx509");
    samlIssuerCfg.setKeyStoreConfig(ksc);
    
    //set the key information for use with digital signature in the provider config object
    KeyInformationConfig kic = samlFactory.newKeyInformationConfig("mySignAlias", "password", "CN=ME");
    samlIssuerCfg.setKeyInformationConfig(kic);
    
    //create a new SAMLToken object that is a signed clone of the input token
    SAMLToken myNewSamlToken = samlFactory.newSAMLToken(mySamlToken,reqData,samlIssuerCfg);
  4. Inspect the SAML token XML to see modifications
    //get the SAML Assertion element
    OMElement samlElement = ((OMStructure) myNewSamlToken.getXML()).getNode();
    
    //convert the element to a String
    String xmlString = samlElement.toString();