A number of questions regarding integrating DataPower with TFIM have come to me over the last few months, usually along the lines of "it doesn't work". Virtually all of these questions or issues have been caused by mis-configuration, mis-understanding or both, so I think its time for a refresher. This is the first entry in a series of posts that will explore some of the ways the TFIM integration point on DataPower can be used.
DataPower uses the TFIM Security Token Service (STS) for WS-Security token verification, mapping and exchange. The TFIM STS supports or implements the WS-Trust protocol, which uses SOAP messages to transport WS-Security tokens.
In this post I'll walk through one of the most straight-forward example of the WS-Security token use case - exchanging a UsernameToken for a SAML assertion using TFIM. In subsequent posts I'll explore how non-WS-Security based identity types can be used on DataPower, as well as exploring some custom integration options.
TFIM STS Overview
The first thing we need to do is configure is the TFIM STS to perform this token exchange. The token exchange is controlled by a TFIM STS entity called a trust chain that defines the token operations undertaken by the TFIM STS such as token validation, mapping and exchange. A trust chain consists of a series of sequentially executed trust modules, with each module performing a specific operation.
The WS-Trust protocol defines a XML-based message format for transporting tokens, usually enclosed with in a SOAP envelope. The specification defines an element called a RequestSecurityToken (RST) that contains the WS-Trust parameters such as tokens and addressing parameters. STS responses to clients are contained within an element RequestSecurityTokenResponse (RSTR).
In our example we'll be validating a UsernameToken (using a UsernameToken trust module), adding an attribute via a Map trust module, and finally issuing a SAML 2.0 assertion using a SAML 2.0 trust module.
TFIM STS Configuration
Trust chain creation is driven by a wizard so let's walk through the steps.
Firstly there's the name of the trust chain itself. While this can be anything, its useful to call it something that reflects what the trust chain is actually doing: In this case using the name UsernameToken to SAML 2.0 indicates the chain will exchange a UsernameToken (UNT) to a SAML 2.0 assertion. A description of they trust chain can be used to provide more information of the trust chain's purpose.
Next, the parameters of the chain's mode of operation and selection criteria are required.
When a WS-Trust message is received by the STS, the WS-Trust elements of the request are matched against the WS-Trust elements of all the configured trust chains. Specifically, the mode of operation (Validate, Issue, Exchange), AppliesTo, Issuer and TokenType parameters are used to match a trust chain to incoming WS-Trust messages.
Note: WS-Trust version 1.2 and 1.3 use different URIs, namespace declarations and values to describe the mode of operation. In this example we'll be using WS-Trust version 1.3, which corresponds to the “Validate OASIS URI” Request Type option.
To invoke this trust chain, the WS-Trust RST must have:
an AppliesTo value that ends in UsernameToSAML20
an Issuer value that is urn:ibm:datapower
An important item to note is the AppliesTo field. The trust chain uses a regular expression macro that will match all RST requests that have an AppliesTo value that ends in UsernameToSAML20.
The WS-Trust values of the trust chain configured above will be used later when configuring the DataPower TFIM object.
Once the WS-Trust parameters of the trust chain have been configured, the trust modules that operate on the tokens can be configured. The standard sequence for trust chain processing is thus:
Validate the input token;
[Optional] Map the identity of the token or add attributes;
Issue a new token.
For this example, we need to configure a UsernameToken module in Validate mode, a Map module in Map mode and a SAML 2.0 module in Issue mode.
Once the order of trust modules has been configured and their operating modes defined, the last step is configuring specific processing options for each module.
Firstly, the UsernameToken module. In the DataPower use case, the user's password has more often than not already been verified. To avoid the un-necessary step of re-validating the password, we can use the Skip Password Validation option. The length of time (in seconds) the UsernameToken is considered valid can also be configured here, but for simplicity we won't configure that feature. A value of -1 indicates that the module will never check for the token's validity.
Note: Save this snippet as a file and upload to TFIM.
Lastly, the properties of the SAML assertion issued by TFIM can be configured, such as signing and encryption of the assertion. For the current example, the most significant items are:
the name of the organisation issuing the assertion;
attributes to include in the assertion;
un-checking the Sign assertion checkbox.
TFIM Trust Chain Summary
So let's recap: We've created a TFIM trust chain, configured its WS-Trust parameters and a sequence of trust modules that validate a UsernameToken and issue a SAML assertion. The summary screen displays the trust chain's configuration:
Now we can begin setting up the DataPower appliance to use the TFIM STS.
DataPower TFIM Object
Configure a DataPower TFIM object to interact with the TFIM STS. Create a new one by navigating to Objects -> Access -> Tivoli Federated Identity Manager and click Add. Then, configure the object as shown:
So what does all of that mean? The following bullets will explain, but the DataPower online help should also be used for reference.
Endpoint Type indicates that the object is to be used for Token Mapping, not Oauth.
Server and Port fields should be self-explanatory: They're the host and port that the TFIM STS is listening on.
Compatibility Mode indicates the version of WS-Trust that is to be used. TFIM 6.2 introduced support for WS-Trust 1.3, so selecting Version 6.2 means the DataPower TFIM client will use WS-Trust 1.3 when communicating with the TFIM STS. Refer to the online help for more details, but this field is very important when interacting with TFIM.
Request Token Format is often mis-interpreted, but it defines the type of the WS-Security token that the DataPower TFIM client will look for in the AAA context to send to TFIM.
In this example, the Request Token Format is UsernameToken, as this the WS-Security token in the AAA context.
AppliesTo Address and Issuer are the WS-Trust parameters that TFIM uses to identify the correct trust chain.
DataPower AAA Object Configuration
Now this TFIM object can be added to a DataPower AAA policy; we'll be adding the object to the Post Processing phase of the AAA policy.
To create a AAA policy navigate to Objects -> XML Processing -> AAA Policy and click Add. The policy should be configured as follows:
- Extract Identity: Password-carrying UsernameToken element from WS-Security header
- Authentication: AAA Information file (in production systems this would more likely be LDAP or ISAM). An example has been provided at the end of this post.
- Credential mapping: None
- Resource extraction: Local name of request element
- Resource mapping: None
- Authorization: Allow any authenticated client
- Request Tivoli Federated Identity Manager token mapping: On
- Tivoli Federated Identity Manager endpoint: UsernameTokenProcessing
- Replacement method: All
- Retrieval method: Call Tivoli Federated Identity Manager
What does this AAA policy configuration mean in practice?
The policy will first look for and extract the username and password from a UsernameToken, and then use a AAA information file to authenticate the user. No immediate credential mapping will occur, and the policy will also extract the local name of the input SOAP message as the resource being requested. No specific authorization is being performed (beyond allowing authenticated users), and so processing flows into the post processing phase where the DataPower TFIM object is used.
Selecting the Request Tivoli Federated Identity Manager token mapping option displays the available TFIM mapping options.
Tivoli Federated Identity Manager endpoint identifies the particular TFIM object to be used.
Replacement method defines how existing WS-Security tokens are treated if tokens are returned from TFIM. In this case, we want the UsernameToken replaced by the TFIM-issued SAML assertion, so the All option is used.
Token mapping using TFIM can be performed during the AAA policy's Credential mapping stage, and if so any token returned during this phase can be inserted here. This example doesn't do this, so the Call Tivoli Federated Identity Manager option is selected (to contact the TFIM STS for a token).
A subsequent post will describe how the Replacement and Retrieval options can be used differently.
DataPower Configuration Summary
Time for another recap. We've created the following artifacts:
A TFIM trust chain, configured its WS-Trust parameters and a sequence of trust modules that validate a UsernameToken and issue a SAML assertion.
A DataPower TFIM object with the following properties:
Communicates with the TFIM STS using WS-Trust 1.3 (Version 6.2)
Looks for a UsernameToken in the input AAA context
AppliesTo and Issuer fields that correspond to the WS-Trust parameters of the desired TFIM trust chain
A DataPower AAA policy that
Authenticates a username and password from an input UsernameToken
Uses a DataPower TFIM object to send the UsernameToken to the TFIM STS in the Post processing phase of the AAA policy
DataPower Test Service
All that's left now is to apply the AAA policy to a DataPower service.
For simplicity we'll use a XML Firewall for this demo, so navigate to Control Panel -> XML Firewall and click Add Wizard.
Note: Multi-Protocol Gateway services are usually a better option for production deployments.
On the first page of the wizard, select Access Control (AAA) as the XML Firewall type, click Next
On the next screen choose Loopback as the service type as we're not sending the request to a backend service.
The next screen defines which TCP port the XML Firewall service will listen for requests on. Choose a port that's not in use or accept the default, ensuring that SSL is disabled:
Choose the AAA policy that was created earlier:
Review the XML Firewall summary and commit the new service:
Testing the Integration
Now we're ready to test the DataPower / TFIM token exchange operation.
To view the interaction between DataPower and TFIM, we need to enable the DataPower debug probe utility on the XML Firewall service. Navigate to Control Panel -> Troubleshooting -> Debug Probe, and add a probe for the XML Firewall service by clicking Add Probe for the XML Firewall service you created (UsernameTokenExchange).
Using curl, we'll send the sample SOAP message included at the end of this blog entry to the XML firewall service. Here's what we expect to happen:
The XML Firewall service will invoke the AAA policy that is configured in its processing policy.
The AAA policy will extract the username and password from the UsernameToken (msmith / passw0rd) and validate it against the AAA information file.
The Post processing phase of the AAA policy will use a DataPower TFIM object to send the UsernameToken to the TFIM STS in a WS-Trust RequestSecurityToken message.
The TFIM STS will select a trust chain based on the input RST, add a custom attribute and issue a SAML 2.0 assertion
The SAML 2.0 assertion will be sent back to DataPower in a RequestSecurityTokenResponse (RSTR) message.
The DataPower AAA policy will replace the existing UsernameToken with the SAML assertion issued by TFIM.
Send the test message to the DataPower XML Firewall service as a binary POST:
$ curl -v --data-binary @<path to sample-request.xml> http://<datapower hostname>:<XMLFW port>/demo
The result is the input message, but now with an SAML 2.0 assertion included in the WS-Security header:
The significant parts of the SAML assertion issued by TFIM are described below. They are significant as they clearly match the configuration of the SAML token module that was configured.
The additional context attribute called "operation" was added in the TFIM Map module:
<saml:Attribute Name="operation" NameFormat="example"><saml:AttributeValue xsi:type="xs:string">NotSpecified</saml:AttributeValue></saml:Attribute>
Because we didn't do any identity mapping, the subject of the assertion is the same as the username in the UsernameToken sent to TFIM:
The issuer is IBM:
But what actually happened between DataPower and TFIM? This is where we can use the DataPower probe to analyse the transaction. On the Debug probe tab of the Troubleshooting page (Control Panel -> Troubleshooting), click on the icon that resembles a magnifying glass:
This will pop up a new window that lists the transactions received by the XML Firewall service after the probe was enabled (right now there should be only one). To view the details of the transaction, click on the magnifying glass of the Transaction List window, and then on the AAA action icon of the transaction context window that appears:
Clicking on the request and response "show nodeset" links displays the RST sent to TFIM and the RSTR returned to DataPower by TFIM.
This somewhat introductory post has illustrated the step-by-step instructions on how DataPower can utilise the TFIM STS to perform token exchange operations.
Future entries will expand on this concept, introducing some more advanced deployment options and ultimately some custom stylesheet options that can be employed on DataPower to implement scenarios that cannot be supported by native DataPower features.
TFIM mapping file
<xsl:strip-space elements="*" />
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" />
<!-- Identity transform - copy all content -->
<xsl:template match="@* | node()">
<xsl:apply-templates select="@* | node()" />
<!-- The Web service operation is added as an extended attribute -->
<stsuuser:Attribute name="operation" type="example">
DataPower AAA Information File
<?xml version="1.0" encoding="utf-8"?>
<Summary>Sample AAA Information File</Summary>
<demo:data>This is a test message</demo:data>