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


Request SAML sender-vouches tokens from an external STS using WSS APIs and transport level protection

We can request SAML tokens with the sender-vouches subject confirmation method from an external Security Token Service (STS). After obtaining the SAML sender-vouches token, you can then send these tokens with web services request messages using the JAX-WS programming model and Web Services Security APIs (WSS API) with transport level protection.

This task assumes that you are familiar with the JAX-WS programming model, the WSS API interfaces, SAML concepts, SSL transport protection, and the use of policy sets to configure and administer web services settings.

New feature:

You can request a SAML token with the sender-vouches subject confirmation method from an external STS and then send the SAML token in web services request messages from a web services client using WSS APIs with transport level protection. New feature:

The web services client application used in this task is a modified version of the client code that is contained in the JaxWSServicesSamples sample application that is available for download. Code examples from the sample are described in the procedure, and a complete, ready-to-use web services client sample is provided.


Procedure

  1. Identify and obtain the web services client that you want to use to invoke a web services provider.

    Use this client to insert SAML tokens in SOAP request messages programmatically using WSS APIs.

    The web services client used in this procedure is a modified version of the client code that is contained in the JaxWSServicesSamples web services sample application.

    To obtain and modify the sample web services client to add the Web Services Security API to pass SAML sender-vouches tokens in SOAP request messages programmatically using WSS APIs...

    1. Download the JaxWSServicesSamples sample application. The JaxWSServicesSamples sample is not installed by default.
    2. Obtain the JaxWSServicesSamples client code.

      For example purposes, this procedure uses a modified version of the Echo thin client sample that is included in the JaxWSServicesSamples sample. The web services Echo thin client sample file, SampleClient.java, is located in the src\SampleClientSei\src\com\ibm\was\wssample\sei\cli directory. The sample class file is included in the WSSampleClientSei.jar file.

      The JaxWSServicesSamples.ear enterprise application and supporting Java archives (JAR) files are located in the installableApps directory within the JaxWSServicesSamples sample application.

    3. Deploy the JaxWSServicesSamples.ear file onto the application server. After you deploy the JaxWSServicesSamples.ear file, you are ready to test the sample web services client code against the sample application.

    Instead of using the web services client sample, you can choose to add the code snippets to pass SAML tokens in SOAP request messages programmatically using WSS APIs in your own web services client application. The example in this procedure uses a JAX-WS Web services thin client; however, you can also use a managed client.

  2. Create a copy of either the SAML20 Bearer WSHTTPS default policy set or the SAML11 Bearer WSHTTPS default policy set.

    Provide a name for the copy of the policy set; for example SAML20 SenderVouches WSHTTPS or SAML11 SenderVouches WSHTTPS to help you identify that this new policy set uses the sender-vouches confirmation method.

    No additional change is required to the new policy file because the subject confirmation method is specified in the binding configuration and not in the policy.

    The new policy file contains either SAMLToken20Bearer or the SAMLToken11Bearer as the policy identifiers. Change the identifier of the SAMLToken20Bearer policy to SAMLToken20SV or change the identifier of the SAMLToken11Bearer policy to SAMLToken11SV to specify a more descriptive name. Changing the identifier of the policy does not change the policy enforcement in any way; however, adding a descriptive identifier helps you to identify that these policy identifiers use the sender-vouches confirmation method.

    To view the settings of these policies, use the admin console to complete the following actions:

    1. Click Services > Policy sets > Application policy sets > policy_set_name.

    2. Click the WS-Security policy in the policies table.

    3. Click the Main policy link or the Bootstrap policy link.

    4. Click Request token policies from the Policy Details section.

  3. Attach the new SAML20 SenderVouches WSHTTPS or SAML11 SenderVouches WSHTTPS policy set to the web services provider application. Read about configuring client and provider bindings for the SAML sender-vouches token for details on attaching this policy set to your web services provider application.

  4. Create a copy of the SAML Bearer Provider sample default general bindings.

    1. For the new copy of the default policy set, provide a name that includes sender-vouches, such as SAML Sender-vouches provider binding.

    2. In the callback handler of your SAML11 or SAML20 token consumer, change the value of the confirmationMethod property to sender-vouches in the token consumer configuration for the intended SAML token version. Ensure that the custom properties trustStoreType, trustStorePassword and trustStorePath correspond to the trust store containing the STS signer certificate. Read about configuring client and provider bindings for the SAML sender-vouches token for details on modifying the sender-vouches bindings to satisfy the vouching requirement.

  5. Assign the new provider binding to the JaxWSServicesSamples provider sample. Read about configuring client and provider bindings for the SAML sender-vouches for details on assigning the SAML sender-vouches provider sample, default general bindings to your web services provider application.
  6. Enable the web services provider SSL configuration attribute, clientAuthentication, to require X.509 client certificate authentication.

    The clientAuthentication attribute determines whether SSL client authentication is required.

    To specify the clientAuthentication attribute, use the admin console to complete the following actions:

    1. Click Security > SSL certificates and key management > Manage endpoint security configurations > {Inbound | Outbound} > SSL_configuration .

    2. Click the WC_defaulthost_secure link in the inbound topology.

    3. From Related Items, click the SSL_configurations link.

    4. Select the NodeDefaultSSLSettings resource.

    5. Click Quality of protection (QoP) settings link.

    6. Select Required from the menu to specify client authentication.

    Read about creating a secure sockets layer configuration to learn more about configuring the clientAuthentication attribute.

  7. Specify to use SSL transport-level message protection. Use the following JVM property to specify to use SSL to protect the SAML token request with the STS:
    -Dcom.ibm.SSL.ConfigURL=file:PROFILE_ROOT\properties\ssl.client.props
    
    Alternatively, you can define the SSL configuration file using a Java system property in the sample client code; for example:
    System.setProperty("com.ibm.SSL.ConfigURL", "file:PROFILE_ROOT/properties/ssl.client.props");
    

  8. Add the Thin Client for JAX-WS JAR file to the class path. Add the WAS_HOME/runtimes/com.ibm.jaxws.thinclient_8.0.0.jar file to the class path. See the testing web services-enabled clients information for more information about adding this JAR file to the class path.
  9. Request the SAML token from an external STS. The following code snippet illustrates how to request the SAML sender-vouches token and assumes that an external STS is configured to accept a UsernameToken, and to issue a SAML 1.1 token using sender-vouches after validation:
    //Request the SAML Token from external STS
    WSSFactory factory = WSSFactory.getInstance();
    String STS_URI  = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
    String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
    WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
    WSSConsumingContext concont1 = factory.newWSSConsumingContext();
    HashMap
    <Object, Object> cbackMap1 = new HashMap
    <Object, Object>();
    cbackMap1.put(SamlConstants.STS_ADDRESS, STS_URI);
    cbackMap1.put(SamlConstants.SAML_APPLIES_TO, ENDPOINT_URL);
    cbackMap1.put(SamlConstants.TRUST_CLIENT_WSTRUST_NAMESPACE, "http://docs.oasis-open.org/ws-sx/ws-trust/200512");
    cbackMap1.put(SamlConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
    cbackMap1.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML11_VALUE_TYPE);
    cbackMap1.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");
    
    SAMLGenerateCallbackHandler cbHandler1 = new SAMLGenerateCallbackHandler(cbackMap1);
    
    // Add UNT to trust request UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
    SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
    
    gencont1.add(ut);
    
    cbHandler1.setWSSConsumingContextForTrustClient(concont1);
    cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
    SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, cbHandler1, "system.wss.generate.saml");
    
    System.out.println("SAMLToken id = " + samlToken.getId());
    

    1. Use the WSSFactory newSecurityToken method to specify how to request the SAML token from an external STS.

      Specify the following method to create the SAML token:

      WSSFactory  newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml")
      

      Request a SAML token requires the Java security permission wssapi.SAMLTokenFactory.newSAMLToken. Use the Policy Tool to add the following policy statement to the Java security policy file or the application client was.policy file:

      permission java.security.SecurityPermission "wssapi.SAMLTokenFactory.newSAMLToken"
      

      The SAMLToken.class parameter specifies the type of security token to create.

      The callbackHandler object contains parameters that define the characteristics of the SAMLToken that you are requesting and other parameters required to reach the STS and obtain the SAML token. The SAMLGenerateCallbackHandler object specifies the configuration parameters described in the following table:

      SAMLGenerateCallbackHandler properties. This table describes the configuration parameters for the SAMLGenerateCallbackHandler object using the sender-vouches confirmation method.

      Property Description Required
      SamlConstants.CONFIRMATION_METHOD Specifies to use the sender-vouches confirmation method. Yes
      SamlConstants.TOKEN_TYPE Token type.

      When a web services client has policy set attachments, this property is not used by the Web Services Security runtime environment.

      Specify the token value type by using the valueType attribute of the tokenGenerator binding configuration.

      The example in this procedure uses a SAML 1.1 token; however, you can also use the WSSConstants.SAML.SAML20_VALUE_TYPE value.

      Yes
      SamlConstants.STS_ADDRESS Specifies the Security Token Service address.

      For the example used in this task topic, the value of this property is set to https to specify to use SSL to protect the SAML Token request.

      We must set the -Dcom.ibm.SSL.ConfigURL property to enable the use of SSL to protect the SAML token request with the STS.

      Yes
      SamlConstants.SAML_APPLIES_TO Target STS address for where you want to use the SAML token. No
      SamlConstants.TRUST_CLIENT_COLLECTION_REQUEST Whether to request from the STS a single token that is enclosed in a RequestSecurityToken (RST) element or multiple tokens in a collection of RST elements that are enclosed in a single RequestSecurityTokenCollection (RSTC) element.

      The default behavior is to request a single token that is enclosed in a RequestSecurityToken (RST) element from the STS.

      Specify a true value for this property indicates to request multiple tokens in a collection of RST elements that are enclosed in a single RequestSecurityTokenCollection (RSTC) element from the STS.

      No
      SamlConstants.TRUST_CLIENT_WSTRUST_NAMESPACE Specifies the WS-Trust namespace that is included in the WS-Trust request.

      The default value is WSTrust 1.3.

      No

      A WSSGenerationContext instance and a WSSConsumingContext instance are also set in the SAMLGenerateCallbackHandler object. The WSSGenerationContext instance must contain a UNTGenerateCallbackHandler object with the information to create the UsernameToken that you want to send to the STS.

      The system.wss.generate.saml parameter specifies the Java Authentication and Authorization Service (JAAS) login module used to create the SAML token. We must specify a JVM property to define a JAAS configuration file that contains the required JAAS login configuration; for example:

      -Djava.security.auth.login.config=
      $PROFILE_ROOT/properties/wsjaas_client.conf
      

      Alternatively, you can specify a JAAS login configuration file by setting a Java system property in the sample client code; for example:

      System.setProperty("java.security.auth.login.config", "
      $PROFILE_ROOT/properties/wsjaas_client.conf");
      
    2. Obtain the token identifier of the created SAML token.

      Use the following statement as a simple test for the SAML token that you created:

      .println("SAMLToken id = " + samlToken.getId())
      


Results

You have requested a SAML token with the sender-vouches confirmation method from an external STS. After obtaining the token, you sent the token with web services request messages using transport protection using JAX-WS and WSS APIs.


Example

The following code sample is a complete, ready-to-use web services client application that demonstrates how to request a SAML token from an external STS and send that SAML token in web services request messages with transport level protection. This sample code illustrates the procedure steps described previously.

/**
 * The following source code is sample code created by IBM Corporation.
 * This sample code is provided to you solely for the purpose of assisting you in the
 * use of the technology.  The code is provided 'AS IS', without warranty or condition of  * any kind.  IBM shall not be liable for any damages arising out of your use of the
  *  sample code, even if IBM has been advised of the possibility of such damages.
 */
package com.ibm.was.wssample.sei.cli;

import com.ibm.was.wssample.sei.echo.EchoService12PortProxy;
import com.ibm.was.wssample.sei.echo.EchoStringInput;

import com.ibm.websphere.wssecurity.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.callbackhandler.SAMLGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.saml.config.SamlConstants;

import java.util.Map;
import java.util.HashMap;

import javax.xml.ws.BindingProvider;

public class SampleSamlSVClient {
 private String urlHost = "localhost";
 private String urlPort = "9443";
 private static final String CONTEXT_BASE = "/WSSampleSei/";
 private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";
 private String message = "HELLO";
 private String uriString = "https://" + urlHost + ":" + urlPort;
 private String endpointURL = uriString + ECHO_CONTEXT12;
 private String input = message;

 /**
  * main()
  *
  * see printusage() for command-line arguments
  *
  * @param args
  */
 public static void main(String[] args) {
  SampleSamlSVClient sample = new SampleSamlSVClient();
  sample.CallService();
 }

 /**
  * CallService Parms were already read. Now call the service proxy classes.
  *
  */
 void CallService() {
  String response = "ERROR!:";
  try {

         System.setProperty("com.ibm.SSL.ConfigURL", "PROFILE_ROOT//properties/ssl.client.props");
         System.setProperty("java.security.auth.login.config", "
$PROFILE_ROOT/properties/wsjaas_client.conf");


//Request the SAML Token from external STS
WSSFactory factory = WSSFactory.getInstance();
String STS_URI  = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
HashMap
<Object, Object> cbackMap1 = new HashMap
<Object, Object>();
cbackMap1.put(SamlConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(SamlConstants.SAML_APPLIES_TO, ENDPOINT_URL);
cbackMap1.put(SamlConstants.TRUST_CLIENT_WSTRUST_NAMESPACE, "http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(SamlConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
cbackMap1.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML11_VALUE_TYPE);
cbackMap1.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");

SAMLGenerateCallbackHandler cbHandler1 = new SAMLGenerateCallbackHandler(cbackMap1);

// Add UNT to trust request UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);

gencont1.add(ut);

cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, cbHandler1, "system.wss.generate.saml");

System.out.println("SAMLToken id = " + samlToken.getId());


         // Initialize web services client    EchoService12PortProxy echo = new EchoService12PortProxy();
   echo._getDescriptor().setEndpoint(endpointURL);

   // Configure SOAPAction properties    BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
   Map
<String, Object> requestContext = bp.getRequestContext();
   requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
   requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
   requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");

   // Initialize WSSGenerationContext
   WSSGenerationContext gencont = factory.newWSSGenerationContext();
         gencont.add(samlToken);   
  
  
         // Add timestamp
         WSSTimestamp timestamp = factory.newWSSTimestamp();
   gencont.add(timestamp);
  
         gencont.process(requestContext);
  
         // Build the input object    EchoStringInput echoParm =
    new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
   echoParm.setEchoInput(input);
   System.out.println(">> CLIENT: SEI Echo to " + endpointURL);

   // Prepare to consume timestamp in response message
   WSSConsumingContext concont = factory.newWSSConsumingContext();
       concont.add(WSSConsumingContext.TIMESTAMP);
       concont.process(requestContext);

   // Call the service    response = echo.echoOperation(echoParm).getEchoResponse();

   System.out.println(">> CLIENT: SEI Echo invocation complete.");
   System.out.println(">> CLIENT: SEI Echo response is: " + response);
  } catch (Exception e) {
   System.out.println(">> CLIENT: ERROR: SEI Echo EXCEPTION.");
   e.printStackTrace();
     }
 }
}

When this web services client application sample runs correctly, you receive messages like the following messages:

SAMLToken id = _6CDDF0DBF91C044D211271166233407
Retrieving document at 'file:
$PROFILE_ROOT/.../wsdl/'.
>> CLIENT: SEI Echo to http://localhost:9443/WSSampleSei/EchoService12
>> CLIENT: SEI Echo invocation complete.
>> CLIENT: SEI Echo response is: SOAP12==>>HELLO

Access the samples
SAML concepts
SSL configurations
Secure JAX-WS web services using message-level security
Request SAML sender-vouches tokens from an external STS using WSS APIs and message level protection
Request SAML bearer tokens from an external STS using WSS APIs and transport level protection
Configure client and provider bindings for the SAML sender-vouches token
Send self-issued SAML sender-vouches tokens using WSS APIs with message level protection
Configure client and provider bindings for the SAML bearer token
Test web services-enabled clients
Create an SSL configuration
Samples documentation


Related


SAMLIssuerConfig.properties file
Web Services Security APIs

+

Search Tips   |   Advanced Search