WAS v8.5 > Develop 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 > Attaching the generator token using WSS APIs to protect message authenticity

Configure generator security tokens using the WSS API

We can secure the SOAP messages, without using policy sets, using the Web Services Security APIs. To configure the token on the generator side, use the Web Services Security APIs (WSS API). The generator security tokens are part of the com.ibm.websphere.wssecurity.wssapi.token interface package.

The pluggable token framework in WebSphere Application Server has been redesigned so the same framework from the WSS API can be reused. The same implementation of creating and validating security token can be used both for the Web Services Security runtime and for the WSS API application code. The redesigned framework also simplifies the SPI programming model and will make it easier to add security token types.

We can use the WSS API or we can configure the tokens using the dmgr console. To configure tokens, you must complete the following token tasks:

The JAAS CallbackHandler and JAAS LoginModule are responsible for creating the security token on the generator side.

On the generator side, the token is created using the JAAS LoginModule and using JAAS CallbackHandler to pass authentication data. Then, the JAAS LoginModule creates the securityToken object, such as the UsernameToken, and passes it to the Web Services Security run time.

On the consumer side, the XML format is passed to the JAAS LoginModule for validation or authentication. then the JAAS CallbackHandler is used to pass authentication data from the Web Services Security runtime to the LoginModule. After the token is authenticated, a security token object is created, and the token is passed it to the Web Services Security runtime.

When using the WSS API for generator token creation, certain default behaviors occur. The simplest way to use the WSS API is to use the default behavior (see the example code). The WSS API provide default values for the token type, the token value, and the JAAS confirmation name. The default token behaviors include:

Token decisions and default behaviors. Several token characteristics are configured by default.

Generator token decisions Default behavior
Which token type to use

The token type specifies which type of token to use for message integrity, message confidentiality, or message authenticity.

WAS provides the following pre-configured generator token types for message integrity and message confidentiality:

We can also create custom token types, as needed.

WAS also provides the following pre-configured generator token types for the message authenticity:

We can also create custom token types, as needed.

What JAAS login configuration name to specify

The JAAS login configuration name specifies which JAAS login configuration name to use.

Which configuration type to use The JAAS login module specifies the configuration type. Only the pre-configured generator configuration types can be used for generator token types.

The SecurityToken class (com.ibm.websphere.wssecurity.wssapi.token.SecurityToken) is the generic token class and represents the security token that has methods to get the identity, the XML format, and the cryptographic keys. Using the SecurityToken class, we can apply both the signature and encryption to the SOAP message. However, to apply both, you must have two SecurityToken objects, one for the signature and one for encryption, respectively.

The following tokens types are subclasses of the generic security token class:

Subclasses of the SecurityToken. Use the subclasses to represent the security token.

Token type JAAS login configuration name
Username token system.wss.generate.unt
Security context token system.wss.generate.sct
Derived key token system.wss.generate.dkt

The following tokens types are subclasses of the binary security token class:

Subclasses of the BinarySecurityToken. Use the subclasses to represent the binary security token.

Token type JAAS login configuration name
LTPA token system.wss.generate.ltpa
LTPA propagation token system.wss.generate.ltpaProp
X.509 token system.wss.generate.x509
X.509 PKI Path token system.wss.generate.pkiPath
X.509 PKCS7 token system.wss.generate.pkcs7

  1. To configure the securityToken package, com.ibm.websphere.wssecurity.wssapi.token, first ensure the application server is installed.

  2. Use the Web Services Security token generator process to configure the tokens. For each token type, the process is similar to the following process that demonstrates the UsernameToken token generator process:

    1. Use WSSFactory.getInstance() to get the WSS API implementation instance.

    2. Create the WSSGenerationContext instance from the WSSFactory instance.

    3. Create a JAAS CallbackHandler. The authentication data, such as the user name and password are specified as part of the CallbackHandler. For example, the following code specifies Chris as the user name and sirhC as the password: UNTGenerationCallbackHandler("Chris", "sirhC");
    4. Call any JAAS CallbackHandler parameters and review the token class information for which parameters are required or optional. For example, for the UsernameToken, the following parameters can be configured also:

      Nonce

      Indicates whether a nonce is included in the user name token for the token generator. Nonce is a unique, cryptographic number that is embedded in a message to help stop repeat, unauthorized attacks of user name tokens. The nonce value is valid only when the generated token type is a UsernameToken and only when it applies to the request generator binding.

      Created timestamp

      Indicates whether to insert a time stamp into the UsernameToken. The timestamp value is valid only when the generated token type is a UsernameToken and only when it applies to the request generator binding.

    5. Create the SecurityToken from WSSFactory.

      By default, the UsernameToken API specifies the ValueType as: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken"

      By default, the UsernameToken API provides the QName of this class and specifies the NamespaceURI as http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd and also specifies the LocalPart as UsernameToken.

    6. Optional: Specify the JAAS login module configuration name. On the generator side, the configuration type is always generate (for example, system.wss.generate.unt).

    7. Add the SecurityToken to the WSSGenerationContext.
    8. Call WSSGenerationContext.process() and generate the WS-Security header.


Results

If there is an error condition, a WSSException is provided. If successful, the WSSGenerationContext process() is called, and the security token for the generator binding is attached.


Example

The following example code shows how to use WSS APIs to create a Username security token, attach the Username token to the SOAP message, and configure the Username token in the generator binding.

// import the packages
import javax.xml.ws.BindingProvider;
import com.ibm.websphere.wssecurity.wssapi.*;
import com.ibm.websphere.wssecurity.callbackhandler.*;
...
   // obtain the binding provider    BindingProvider bp = ... ;

   // get the request context    Map<String, Object> reqContext = bp.getRequestContext();

   // generate WSSFactory instance    WSSFactory factory = WSSFactory.getInstance();

   // generate WSSGenerationContext instance    WSSGenerationContext gencont = factory.newWSSGenerationContext();

   // generate callback handler    UNTGenerateCallbackHandler untCallbackHandler = 
   new UNTGenerateCallbackHandler("Chris", "sirhC");

   // generate the username token 
   SecurityToken unt = factory.newSecurityToken(UsernameToken.class, untCallbackHandler);

   // add the SecurityToken to the WSSGenerationContext
   gencont.add(unt);

   // generate the WS-Security header
   gencont.process(reqContext);

The following example code shows how to modify the preceding Username token sample to create an LTPAv2 token from the runAs identity on the current thread. The two lines of code that instantiate the callback handler and create the security token are replaced with the following two lines of code:

// generate callback handler LTPAGenerateCallbackHandler ltpaCallbackHandler = new LTPAGenerateCallbackHandler(null, null);

// generate the LTPAv2 token 
SecurityToken ltpa = wssfactory.newSecurityToken(LTPAv2Token.class, ltpaCallbackHandler);

The instantiation of the LTPAGenerateCallbackHandler object with (null, null) indicates the LTPA token should be generated from the current runAs identity. If the callback handler is instantiated with basicAuth information, ("userName", "password"), a new LTPA token is created using the specified basicAuth information.

The following example shows how to use secure conversation with the WSS APIs to configure the generator tokens, as well as the consumer tokens. In this example, the SecurityContextToken token is created using the WS-SecureConversation draft namespace: http://schemas.xmlsoap.org/ws/2005/02/sc/sct. To use the WS-SecureConversation version 1.3 namespace, http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/sct, specify SecurityContextToken13.class instead of SecurityContextToken.class.

// import the packages
import javax.xml.ws.BindingProvider;
import com.ibm.websphere.wssecurity.wssapi.*;
import com.ibm.websphere.wssecurity.callbackhandler.*;
...
   // obtain the binding provider    BindingProvider bp = ... ;

   // get the request context    Map<String, Object> reqContext = bp.getRequestContext();

   // generate WSSFactory instance    WSSFactory wssFactory = WSSFactory.getInstance();

   WSSGenerationContext bootstrapGenCon = wssFactory.newWSSGenerationContext();

   // Create a Timestamp
   ...
   // Add Timestamp
   ...

   // Sign the SOAP Body, WS-Addressing headers, and Timestamp
   X509GenerateCallbackHandler btspReqSigCbHandler = new X509GenerateCallbackHandler(...);
   SecurityToken btspReqSigToken = wssFactory.newSecurityToken(X509Token.class,
                                                               btspReqSigCbHandler);
   WSSSignature bootstrapReqSig = wssFactory.newWSSSignature(btspReqSigToken);
   bootstrapReqSig.setCanonicalizationMethod(WSSSignature.EXC_C14N);

   // Add Sign Parts
   ...
   bootstrapGenCon.add(bootstrapReqSig);

   // Encrypt the SOAP Body and the Signature
   X509GenerateCallbackHandler btspReqEncCbHandler = new X509GenerateCallbackHandler(...);
   SecurityToken btspReqEncToken = wssFactory.newSecurityToken(X509Token.class,
                                                               btspReqEncCbHandler);
   WSSEncryption bootstrapReqEnc = wssFactory.newWSSEncryption(btspReqEncToken);
   bootstrapReqEnc.setEncryptionMethod(WSSEncryption.AES128);
   bootstrapReqEnc.setKeyEncryptionMethod(WSSEncryption.KW_RSA15);

   // Add Encryption parts    ...
   bootstrapGenCon.add(bootstrapReqEnc);
   WSSConsumingContext bootstrapConCon = wssFactory.newWSSConsumingContext();
   X509ConsumeCallbackHandler btspRspVfyCbHandler = new X509ConsumeCallbackHandler(....);
   WSSVerification bootstrapRspVfy = wssFactory.newWSSVerification(X509Token.class,
                                                                   btspRspVfyCbHandler);
   bootstrapRspVfy.addAllowedCanonicalizationMethod(WSSVerification.EXC_C14N);

   // Add Verify parts    ...
   bootstrapConCon.add(bootstrapRspVfy);
   X509ConsumeCallbackHandler btspRspDecCbHandler = new X509ConsumeCallbackHandler(...);
   WSSDecryption bootstrapRspDec = wssFactory.newWSSDecryption(X509Token.class,
                                                               btspRspDecCbHandler);
   bootstrapRspDec.addAllowedEncryptionMethod(WSSDecryption.AES128);
   bootstrapRspDec.addAllowedKeyEncryptionMethod(WSSDecryption.KW_RSA15);

   // Add Decryption parts    ...
   bootstrapConCon.add(bootstrapRspDec);
   SCTGenerateCallbackHandler sctgch = new SCTGenerateCallbackHandler(bootstrapGenCon,
                                                                      bootstrapConCon,
                                                                      ENDPOINT_URL,
                                                                      WSSEncryption.AES128);
   SecurityToken[] scts = wssFactory.newSecurityTokens(new Class[]{SecurityContextToken.class},
                                                       sctgch);
   SecurityContextToken sct = (SecurityContextToken)scts[0];

   // Use the SCT to generate DKTs for Secure Conversation
   // Signature algorithm and client and service labels
   DerivedKeyToken dktSig = sct.getDerivedKeyToken(WSSSignature.HMAC_SHA1,
                                                   "WS-SecureConversation",
                                                   "WS-SecureConversation");

   // Encryption algorithm and client and service labels
   DerivedKeyToken dktEnc = sct.getDerivedKeyToken(WSSEncryption.AES128,
                                                   "WS-SecureConversation",
                                                   "WS-SecureConversation");

   // Create the application generation context for the request message    WSSGenerationContext applicationGenCon = wssFactory.newWSSGenerationContext();

   // Create and add Timestamp
   ...

   // Add the derived key token and Sign the SOAP Body and WS-Addressing headers
   WSSSignature appReqSig = wssFactory.newWSSSignature(dktSig);
   appReqSig.setSignatureMethod(WSSSignature.HMAC_SHA1);
   appReqSig.setCanonicalizationMethod(WSSSignature.EXC_C14N);
   ...
   applicationGenCon.add(appReqSig);

   // Add the derived key token and Encrypt the SOAP Body and the Signature
   WSSEncryption appReqEnc = wssFactory.newWSSEncryption(dktEnc);
   appReqEnc.setEncryptionMethod(WSSEncryption.AES128);
   appReqEnc.setTokenReference(SecurityToken.REF_STR);
   appReqEnc.encryptKey(false);
   ...
   applicationGenCon.add(appReqEnc);

   // Create the application consuming context for the response message    WSSConsumingContext applicationConCon = wssFactory.newWSSConsumingContext();

   //client and service labels and decryption algorithm
   SCTConsumeCallbackHandler sctCbHandler = new SCTConsumeCallbackHandler("WS-SecureConversation",
                                                                          "WS-SecureConversation",
                                                                          WSSDecryption.AES128);

   // Derive the token from SCT and use it to Decrypt the SOAP Body and the Signature
   WSSDecryption appRspDec = wssFactory.newWSSDecryption(SecurityContextToken.class,
                                                         sctCbHandler);
   appRspDec.addAllowedEncryptionMethod(WSSDecryption.AES128);
   appRspDec.encryptKey(false);
   ...
   applicationConCon.add(appRspDec);

   // Derive the token from SCT and use it to Verify the    // signature on the SOAP Body, WS-Addressing headers, and Timestamp
   WSSVerification appRspVfy = wssFactory.newWSSVerification(SecurityContextToken.class,
                                                             sctCbHandler);
   ...
   applicationConCon.add(appRspVfy);
   ...
   applicationGenCon.process(reqContext);
   applicationConCon.process(reqContext);

For each token type, configure the token using the WSS APIs or using the dmgr console. Next, specify the similar consumer tokens if we have not done so.

If both the generator and consumer tokens are configured, continue securing SOAP messages either by signing the SOAP message or by encrypting the message, as needed. We can use either the WSS APIs or the dmgr console to secure the SOAP messages.


Related concepts:

Security token
Username token
Binary security token
Derived key token
Security context token


Related


Secure messages at the request generator using WSS APIs


Reference:

Protection token settings (generator or consumer)
Callback handler settings for JAX-WS


+

Search Tips   |   Advanced Search