Security Global Forum

Security Global Forum

Our mission is to provide clients with an online user community of industry peers and IBM experts, to exchange tips and tricks, best practices, and product knowledge. We hope the information you find here helps you maximize the value of your IBM Security solutions.

 View Only

Using CURL to send requests to the TFIM Security Token Service

By Shane Weeden posted Wed October 07, 2009 12:00 AM

  

When developing a particular integration or identity mediation which utilizes the Tivoli Federated Identity Manager Security Token Service (TFIM STS), I often test the configured trust chains using a command line driven RequestSecurityToken message with the curl utility.

The purpose of this blog entry is to show you how to do the same thing, assuming you have a familiarity with Tivoli Federated Identity Manager and configuring trust chains in the STS. The instructions in this blog entry are targeted at TFIM 6.2.

A word about TFIM STS and WS-Trust

TFIM has two different STS endpoints – one for WS-Trust 1.2, and the other for WS-Trust 1.3.

The URL for the TFIM WS-Trust 1.2 endpoint is (your hostname and port may vary):

http://localhost:9080/TrustServer/SecurityTokenService

The URL for the TFIM WS-Trust 1.3 endpoint is (your hostname and port may vary):

http://localhost:9080/TrustServerWST13/services/RequestSecurityToken

The shipped STS client that comes with TFIM 6.2 (fixpack 1 and later) is based on the Higgins Project. There are good examples of using this client in my developerworks article on Using WebSEAL Without a User Registry, and an updated version of the STS Client wrappers I developed for that article are available in this blog entry. This Higgins STS client uses WS-Trust 1.2 only, and as such it should be pointed at the TFIM WS-Trust 1.2 endpoint.

A good example of the an exploiter of the WS-Trust 1.3 endpoint is WebSEAL Kerberos Junctions.

If you have WebSphere security enabled, you may need to change your Security role to user/group mapping for the ITFIMRuntime application to allow external WS-Trust requests. This is done in the WebSphere administration console by navigating to Applications -> Enterprise Applications, selecting the ITFIMRuntime application, then selecting Security role to user/group mapping. Modify TrustClientRole and TrustClientInternalRole as shown:

Alternatively (or in addition), read my blog entry on STS Chain Authorization.

In the rest of this post I will introduce an example scenario and show examples of how to drive tests to that same trust chain via both WS-Trust 1.2 and WS-Trust 1.3 using curl and a text file containing the STS request.

Example Scenario

Imagine a simple configuration where you are trying to test the creation of a UsernameToken from a generic XML STSUniversalUser token.
The trust chain configuration may have just two modules: STSUU (validate) -> UsernameToken (issue)

For this scenario we will configure the trust chain mapping parameters as follows:

  • Request type: Validate (http://schemas.xmlsoap.org/ws/2005/02/trust/Validate) Note: This is actually a WS-Trust 1.2 request type URI, however it really doesn’t matter to the TFIM STS what the value is – it will simply be used as a value to match against the incoming request.
  • Issuer Address: http://issuer/stsuu
  • AppliesTo Address: http://appliesto/ut

The configuration of the trust chain in the TFIM Management Console should look like this:

The STSUniversalUser token module has no specific configuration requirements. The UsernameToken module (in issue mode) has some configuration options. For this example, here’s the configuration options I picked:

The STSUniversalUser token is a simple internal token format that TFIM uses as a common XML schema for identity mapping. The complete STSUniversalUser token that we will use to exchange for a UsernameToken is:

<stsuuser:STSUniversalUser xmlns:stsuuser="urn:ibm:names:ITFIM:1.0:stsuuser">
  <stsuuser:Principal>
    <stsuuser:Attribute name="name">
      <stsuuser:Value>john</stsuuser:Value>
    </stsuuser:Attribute>
    <stsuuser:Attribute name="Password">
      <stsuuser:Value>abcd1234</stsuuser:Value>
    </stsuuser:Attribute>
  </stsuuser:Principal>
  <stsuuser:AttributeList />
</stsuuser:STSUniversalUser>

Sending a WS-Trust 1.2 Request

Save the following RequestSecurityToken 1.2 message in a file (e.g. rst.xml):

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:soapenc=”http://schemas.xmlsoap.org/soap/encoding/”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:wsa=”http://schemas.xmlsoap.org/ws/2004/08/addressing”
xmlns:wsp=”http://schemas.xmlsoap.org/ws/2004/09/policy”
xmlns:wst=”http://schemas.xmlsoap.org/ws/2005/02/trust”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
<soapenv:Header/>
<soapenv:Body>
<wst:RequestSecurityToken>
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Validate</wst:RequestType>
<wst:Issuer>
<wsa:Address>http://issuer/stsuu</wsa:Address>
</wst:Issuer>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>http://appliesto/ut</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:Base>
<stsuuser:STSUniversalUser xmlns:stsuuser=”urn:ibm:names:ITFIM:1.0:stsuuser”>
<stsuuser:Principal>
<stsuuser:Attribute name=”name”>
<stsuuser:Value>john</stsuuser:Value>
</stsuuser:Attribute>
<stsuuser:Attribute name=”Password”>
<stsuuser:Value>abcd1234</stsuuser:Value>
</stsuuser:Attribute>
</stsuuser:Principal>
<stsuuser:AttributeList />
</stsuuser:STSUniversalUser>
</wst:Base>
</wst:RequestSecurityToken>
</soapenv:Body>
</soapenv:Envelope>

Use curl to send it to the WS-Trust 1.2 endpoint (xmllint is optional, but nice):

curl --header "soapaction: blah" --header "Content-Type: text/xml" 
    --data-binary @rst.xml http://localhost:9080/TrustServer/SecurityTokenService | xmllint --format -

You should observe a response similar to:

<?xml version=”1.0″?>
<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:soapenc=”http://schemas.xmlsoap.org/soap/encoding/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
<soapenv:Header/>
<soapenv:Body>
<wst:RequestSecurityTokenResponse xmlns:wst=”http://schemas.xmlsoap.org/ws/2005/02/trust” xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd” wsu:Id=”uuid2e8acac6-0124-1f46-ade6-863d156b6d43″>
<wsp:AppliesTo xmlns:wsa=”http://schemas.xmlsoap.org/ws/2004/08/addressing” xmlns:wsp=”http://schemas.xmlsoap.org/ws/2004/09/policy”>
<wsa:EndpointReference>
<wsa:Address>http://appliesto/ut</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:RequestedSecurityToken>
<wss:UsernameToken xmlns:wss=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd” wsu:Id=”username2e8acad5-0124-114e-ad53-863d156b6d43″>
<wss:Username>john</wss:Username>
<wss:Nonce EncodingType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary”>GvIiSf14fvbyy8lFBjb7iw==</wss:Nonce>
<wsu:Created>2009-10-07T10:28:18Z</wsu:Created>
<wss:Password Type=””>abcd1234</wss:Password>
</wss:UsernameToken>
</wst:RequestedSecurityToken>
<wst:RequestedAttachedReference xmlns:wss=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>
<wss:SecurityTokenReference>
<wss:Reference xmlns:wss=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” URI=”#username2e8acad5-0124-114e-ad53-863d156b6d43″ ValueType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken”/>
</wss:SecurityTokenReference>
</wst:RequestedAttachedReference>
<wst:Status>
<wst:Code>http://schemas.xmlsoap.org/ws/2005/02/trust/status/valid</wst:Code>
</wst:Status>
</wst:RequestSecurityTokenResponse>
</soapenv:Body>
</soapenv:Envelope>

Sending a WS-Trust 1.3 Request

Save the following RequestSecurityToken 1.3 message in a file (e.g. rst13.xml):

<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:ns1=”http://docs.oasis-open.org/ws-sx/ws-trust/200512″
xmlns:wsa=”http://schemas.xmlsoap.org/ws/2004/08/addressing”
xmlns:wsp=”http://schemas.xmlsoap.org/ws/2004/09/policy”
xmlns:wst=”http://docs.oasis-open.org/ws-sx/ws-trust/200512″>
<SOAP-ENV:Body>
<ns1:RequestSecurityTokenCollection>
<ns1:RequestSecurityToken>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>http://appliesto/ut</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:Issuer>
<wsa:Address>http://issuer/stsuu</wsa:Address>
</wst:Issuer>
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Validate</wst:RequestType>
<wst:Base>
<stsuuser:STSUniversalUser xmlns:stsuuser=”urn:ibm:names:ITFIM:1.0:stsuuser”>
<stsuuser:Principal>
<stsuuser:Attribute name=”name”>
<stsuuser:Value>john</stsuuser:Value>
</stsuuser:Attribute>
<stsuuser:Attribute name=”Password”>
<stsuuser:Value>abcd1234</stsuuser:Value>
</stsuuser:Attribute>
</stsuuser:Principal>
<stsuuser:AttributeList />
</stsuuser:STSUniversalUser>
</wst:Base>
</ns1:RequestSecurityToken>
</ns1:RequestSecurityTokenCollection>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Use curl to send it to the WS-Trust 1.3 endpoint:

curl --header "soapaction: blah" 
    --header "Content-Type: text/xml" --data-binary @rst13.xml 
    http://localhost:9080/TrustServerWST13/services/RequestSecurityToken | xmllint --format -

You should observe a response similar to:

<?xml version=”1.0″ encoding=”UTF-8″?>
<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:wsa=”http://www.w3.org/2005/08/addressing”>
<soapenv:Header>
<ns1:Security xmlns:ns1=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” soapenv:mustUnderstand=”0″>
<ns2:Timestamp xmlns:ns2=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>
<ns2:Created>2009-10-07T10:26:37Z</ns2:Created>
</ns2:Timestamp>
</ns1:Security>
</soapenv:Header>
<soapenv:Body>
<wst:RequestSecurityTokenResponseCollection xmlns:wst=”http://docs.oasis-open.org/ws-sx/ws-trust/200512″>
<wst:RequestSecurityTokenResponse xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd” wsu:Id=”uuid2e893f9e-0124-1332-8317-863d156b6d43″>
<wsp:AppliesTo xmlns:wsa=”http://www.w3.org/2005/08/addressing” xmlns:wsp=”http://schemas.xmlsoap.org/ws/2004/09/policy”>
<wsa:EndpointReference xmlns:wsa=”http://www.w3.org/2005/08/addressing”>
<wsa:Address>http://appliesto/ut</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:RequestedSecurityToken>
<wss:UsernameToken xmlns:wss=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd” wsu:Id=”username2e893fb1-0124-1be9-a0cd-863d156b6d43″>
<wss:Username>john</wss:Username>
<wss:Nonce EncodingType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary”>ZhfV4AtZMRgCn1U6BBChqQ==</wss:Nonce>
<wsu:Created>2009-10-07T10:26:37Z</wsu:Created>
<wss:Password Type=””>abcd1234</wss:Password>
</wss:UsernameToken>
</wst:RequestedSecurityToken>
<wst:RequestedAttachedReference xmlns:wss=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>
<wss:SecurityTokenReference xmlns:wss=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>
<wss:Reference xmlns:wss=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” URI=”#username2e893fb1-0124-1be9-a0cd-863d156b6d43″ ValueType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken”/>
</wss:SecurityTokenReference>
</wst:RequestedAttachedReference>
<wst:Status>
<wst:Code>http://docs.oasis-open.org/ws-sx/ws-trust/200512/status/valid</wst:Code>
</wst:Status>
</wst:RequestSecurityTokenResponse>
</wst:RequestSecurityTokenResponseCollection>
</soapenv:Body>
</soapenv:Envelope>

There are more valid formats in WS-Trust 1.3 for requests. For example security tokens may appear in the WS-Security header, not just in the wst:Base token. This blog post is not written to teach you about all the valid formats, but just to demonstrate one that works so that you can drive your own command-line test cases.

Random Observations

When using early versions of TFIM 6.2 and WebSphere fixpacks it wasn’t necessary to send the Content-Type: text/xml header. In more recent versions, I have found that if I leave out this header, WebSphere returns the error:
org.xml.sax.SAXParseException: The root element is required in a well-formed document.

Early versions of TFIM required the soapaction header, and in more recent versions that requirement has been removed.

My advice is to stick to the parameters and formats I’ve described above, and it should work for you! Please report any particular issues you encounter so I can update this blog which any new best practices.

0 comments
8 views

Permalink