Consuming Web services across an information system often requires dealing with multiple security token formats. Service providers and consumers are spread over different security domains using different token types or different implementation technologies that don't support a common set of token formats. Using WS-Security to convey user authentication information is not sufficient to ensure authentication interoperability between consumers and providers. This is where the use of WS-Trust can help to leverage consumer transparent mechanisms to perform token transformation with a Security Token Service (STS).
WS-Trust describes a structure aiming at managing, establishing and evaluating trust relations in order to enable web services to interoperate safely. This structure is independent of the security protocols used.
A Security Token Service (STS) is a standard component of a security architecture that enables operations like:
- Identity validation
- Identity mapping
- Security token exchange
As shown in Figure 1, WS-Trust introduces three parties. The STS is the central element because it issues the tokens that service providers trust (or they trust the STS to validate tokens).
Figure 1. WS-Trust security model
WS-Trust defines multiple scenarios. In this article, we'll focus on the token request and issuance scenario. WS-Trust 1.3 defines the Request Token Request as shown in Figure 2.
Figure 2. WS-Trust Token Request
WS-Trust relies on WS-Security to convey the identity of the requester.
The request contains a mandatory field specifying the request type. For a
token request, the value is
TokenType field is optional and enables you
to specify the desired format of the returned token. Possible values of
this field are described in the different WS-Security token profiles
(Username Token Profile, X509 token Profile, and so on). For instance:
- Username Token:
- SAML V2.0 assertion:
AppliesTo field is optional and enables the
requester to specify the endpoint to which the returned token will be
sent. In some cases, the STS is configured to know what token type must be
returned for a specific endpoint.
TokenType fields are both present in the
request, the precedence goes to the
field; that is, if the STS knows that the endpoint uses a different token
type than the one specified in the
field, it ignores the
TokenType field and
returns the token that is used by the endpoint. This assumes that the STS
is the only party knowing what token types are supported by the providers'
endpoints. The advantage of this mechanism is that each consumer doesn't
have to maintain the whole list of supported token types and
OnBehalfOf field enables the requester to
specify that the request is being sent on behalf of another party. In this
case, this field contains the authentication token of the other party.
The STS returns a Request Token Response, as shown in Figure 3, encapsulating the requested token. Actually the response contains a token collection, because WS-Trust uses the same message no matter how many tokens have been requested.
The response message also contains data related to the generated token. Using the optional WS-Trust fields in the response message, the STS can communicate the properties of the generated token, even if the requester can't interpret the information encapsulated in the token itself. For instance, you can provide the issuing time of the token and its lifetime.
Figure 3. WS-Trust Request Token Response
As described on Figure 4, composite applications often need to consume services provided by other applications outside their own system (or security domain). In this case, each application needs to know what token type is supported by each provider.
Figure 4. Base architecture
This raises several issues:
- A gateway must know each token type required by each system.
- The configuration must be repeated for each gateway.
- Any change in a system must be configured several times.
- Some gateways may not support the required token type of a provider.
- Some token formats will require specific exchange with an identity or token provider that the gateway has to handle.
Using an STS to manage the configuration of the various security tokens supported by the providers provides the following advantages:
- The configuration is centralized and easier to maintain.
- The gateways simply request a token for a service endpoint, the token generation is transparent, no matter if the gateway supports the token type or not.
Let's focus on a base scenario, shown in Figure 5, in which a user authenticates on a composite application that needs to consume a service provided by another system located in another domain.
The application uses an ESB relying on a Web service gateway to contact the service external provider. The gateway is responsible for managing the complexity of the interaction with an external provider. From the point of view of the service consumer, all the processing related to the external communication is transparent; that is, the service is consumed like any other service provided in the local domain at the ESB level (especially regarding the security token type used internally).
Figure 5. Base scenario for consuming external services
In our simple example, for internal communications, the service consumer domain relies on a light username token with ID assertion, and no password. The service consumer sends a request that looks like the Listing 1.
Listing 1. Base service request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <To xmlns="http://www.w3.org/2005/08/addressing"> http://testHost/HelloService </To> <Action xmlns="http://www.w3.org/2005/08/addressing"> http://testHost/HelloService/hello </Action> <wsse:Security xmlns:wsse="http://.../oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <wsse:UsernameToken> <wsse:Username>jdoe</wsse:Username> </wsse:UsernameToken> </wsse:Security> </soapenv:Header> <soapenv:Body> … </soapenv:Body> </soapenv:Envelope>
When receiving this request, the ESB relies on the gateway to handle the external communication. As the request must be sent in a domain that may require a different type of token than the one used internally in the consumer domain, the gateway has to perform a token exchange before sending the request to the provider. WS-Trust is used to send a token request to the Security Token Service.
There are two things to note here:
- A trust relationship must be established between the gateway and the STS. Returning a token implies that the STS trusts the requesting system to authenticate the users; this is an organizational aspect. Some technical method must be leveraged to guarantee that the token request is made by the requesting system.
- The identities must be propagated all over the information system (either by using the same user repository or by synchronizing the user repositories of the different systems). WS-Trust doesn't handle federation.
Establishing trust between the gateway and the STS can be done by signing the token request using the gateway's private key.
Listing 2 contains a corresponding request token request sample. You can
see the binary token of the gateway and the signature of the request.
Notice that the field
OnBehalfOf contains the
security token sent by the consumer.
Listing 2. Request Token Request sample
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsu="http://.../oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://.../oasis-200401-wss-wssecurity-secext-1.0.xsd"> <S:Header> <wsse:Security S:mustUnderstand="1"> <wsse:BinarySecurityToken wsu:Id="SecurityToken-id" EncodingType="http://.../oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://.../oasis-200401-wss-x509-token-profile-1.0#X509v3"> Gateway X509 Certificate </wsse:BinarySecurityToken> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> … </SignedInfo> <SignatureValue> … </SignatureValue> <KeyInfo> <wsse:SecurityTokenReference> <wsse:Reference URI="#SecurityToken-id" ValueType="http://.../oasis-200401-wss-x509-token-profile-1.0#X509v3"/> </wsse:SecurityTokenReference> </KeyInfo> </Signature> … </wsse:Security> </S:Header> <S:Body> <RequestSecurityToken xmlns="http://docs.oasis-open.org/ws-sx/ws-trust/200512" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:pol="http://schemas.xmlsoap.org/ws/2004/09/policy"> <RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</RequestType> <pol:AppliesTo> <wsa:EndpointReference> <wsa:Address>http://testHost/HelloService</wsa:Address> </wsa:EndpointReference> </pol:AppliesTo> <OnBehalfOf> <wsse:UsernameToken xmlns:wsse="http://.../oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Username>jdoe</wsse:Username> </wsse:UsernameToken> </OnBehalfOf> <TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0> </RequestSecurityToken> </S:Body> </S:Envelope>
In our example, the STS replies with an embedded SAML V2 assertion as shown in Listing 3.
Listing 3. Request Token Response
<S:Envelope xmlns:wsu="http://.../oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:S="http://www.w3.org/2003/05/soap-envelope"> <S:Header> <wsse:Security xmlns:wsse11="http://.../oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsse="http://.../oasis-200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1"> <wsu:Timestamp> <wsu:Created>2009-11-08T11:03:20Z</wsu:Created> <wsu:Expires>2009-11-08T11:08:20Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </S:Header> <S:Body> <trust:RequestSecurityTokenResponseCollection xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:wsse="http://.../oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> <trust:RequestSecurityTokenResponse> <trust:TokenType> http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType> <trust:RequestedSecurityToken> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="uuid-76a197ba-c2e8-4704-97a2-147db7619f2c" IssueInstant="2009-11-08T11:03:20Z" Version="2.0"> ... <saml:Subject> <saml:NameID NameQualifier="STS">jdoe</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches"/> </saml:Subject> ... </saml:Assertion> </trust:RequestedSecurityToken> <trust:RequestedAttachedReference> <wsse:SecurityTokenReference> <wsse:KeyIdentifier ValueType="http://.../wss/oasis-wss-saml-token-profile-1.1#SAMLID"> uuid-76a197ba-c2e8-4704-97a2-147db7619f2c </wsse:KeyIdentifier> </wsse:SecurityTokenReference> </trust:RequestedAttachedReference> ... <wsp:AppliesTo> <wsa:EndpointReference> <wsa:Address> http://testHost/HelloService</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> <trust:Lifetime> <wsu:Created>2009-11-08T11:03:20.344Z</wsu:Created> <wsu:Expires>2009-11-08T11:09:20.344Z</wsu:Expires> </trust:Lifetime> </trust:RequestSecurityTokenResponse> </trust:RequestSecurityTokenResponseCollection> </S:Body> </S:Envelope>
Note the presence of the
Lifetime field in the
response. This field can be used when the returned token format is not
supported by the requester.
Finally, the gateway can replace the username token in the request of the service consumer and send it to the provider. The service request is then transformed as shown in Listing 4.
Listing 4. Transformed service request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://.../oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="uuid-76a197ba-c2e8-4704-97a2-147db7619f2c" IssueInstant="2009-11-08T11:03:20Z" Version="2.0"> ... <saml:Subject> <saml:NameID NameQualifier="STS">jdoe</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches"/> </saml:Subject> ... </saml:Assertion> </wsse:Security> </soapenv:Header> <soapenv:Body> … </soapenv:Body> </soapenv:Envelope>
This article showed you how you can use WS-Trust to resolve token exchange issues. The interactions are summarized in the sequence diagram in Figure 6.
Figure 6. Sequence diagram of token transformation
To implement a solution such as that described in this article, you can use WebSphere® DataPower SOA appliances as a gateway and Tivoli® Federated Identity Manager as the Security Token Service.
The author would like to thank Arnauld Desprets from IBM Software Group and Stéphane Monfort from IBM Global Business Services for their help with this article.
Web Services Security: Get the specification.
Web Services Trust Language: Get the WS-Trust specification.
Managing identity contexts across service requests: Identity
propagation considerations in a SOA environment (developerWorks
2008): his article discusses the business challenges when managing
identity contexts in Web services and SOA. It outlines the importance of
creating solutions based on standards. The security token service (STS)
capability in IBM® Tivoli® Federated Identity Manager (TFIM) is a key
building block that can be used in solutions to address these identity
propagation requirements. This article explains the capabilities of the
STS and outlines architectural approaches using TFIM to solve these needs.
developerWorks WebSphere Web services and SOA zone: Get the latest
technical resources on IBM WebSphere Web services and SOA solutions,
including downloads, demos, articles, tutorials, events, webcasts, and
Laurent Chades is a Senior Certified IT Architect at IBM Global Business Services in France. He is in charge of designing SOA solutions and serves as technical lead on large projects. He also acts as a consultant, helping customers to leverage SOA technologies and concepts and to define their governance processes. Laurent has over 8 years experience in the IT industry and has been working on SOA solutions design and delivery since 2003.