This article presents the JBoss Security Token Service (JBoss STS). We start with a brief description of the WS-Trust specification. Then we present JBoss STS and discuss its overall architecture. After that we explain how to configure and deploy the service, using an example to clearify the concepts. Finally, we show a sample client application that sends WS-Trust requests to JBoss STS, describing the steps that need to be followed in order to get everything running in JDK 6.
The WS-Trust specification defines extensions that build on WS-Security to provide a framework for requesting and issuing security tokens. Particularly, WS-Trust defines the concept of a security token service (STS), a service that can issue, cancel, renew and validate security tokens, and specifies the format of security token request and response messages.
A security token request message specifies, among other things, the type of the request (issue, renew, etc), the type of the token, the lifetime of the token, information about the service provider that requested the token, and information used to encrypt the generated token. An example of a WS-Trust request message can be seen bellow:
<S11:Envelope xmlns:S11=".." xmlns:wsu=".." xmlns:wst=".."> <S11:Header> ... </S11:Header> <S11:Body wsu:Id="body"> <wst:RequestSecurityToken Context="context"> <wst:TokenType>http://www.tokens.org/SpecialToken</wst:TokenType> <wst:RequestType> http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue </wst:RequestType> </wst:RequestSecurityToken> </S11:Body> </S11:Envelope>
As we can see, the token request message is sent in the body of the SOAP message. All information related to the token request is enclosed in the RequestSecurityToken element. The sample request contains two other WS-Trust elements: RequestType, which specifies that this request is an Issue request, and TokenType, which specifies the type of the token to be issued.
The security token response message specifies, among other things, the type of the token that has been issued, the security token itself, the lifetime of the issued token, and information that will be used by the client to decrypt the security token. An example of a token response is shown bellow:
<wst:RequestSecurityTokenResponse Context="context" xmlns:wst=".." xmlns:wsu=".."> <wst:TokenType>http://www.tokens.org/SpecialToken</wst:TokenType> <wst:RequestedSecurityToken> <token:SpecialToken xmlns:token="..."> ARhjefhE2FEjneovi&@FHfeoveq3 </token:SpecialToken> </wst:RequestedSecurityToken> <wst:Lifetime> <wsu:Created>...</wsu:Created> <wsu:Expires>...</wsu:Expires> </wst:Lifetime> </wst:RequestSecurityTokenResponse>
The figure above shows a WS-Trust response message that contains a custom token. The TokenType element specifies the type of the issued token, while the RequestedSecurityToken element contains the token itself. The format of the token is depends on the token type. The Lifetime element specifies when the token has been created and when it will expire.
Web Services Trust Model
The Web service security model defined in WS-Trust is based on a process in which a Web service can require that an incoming message prove a set of claims (e.g., name, key, permission, capability, etc.). In other words, the Web service can ask for a security token that can provide proof of such claims. A client that invokes the service without providing the token may be asked to get a token from a trusted STS first. Upon getting the token from the STS, the client retries the invocation, this time sending the obtained token in the message.
This model is illustrated in the figure below, showing that any requestor may also be a service, and that the Security Token Service is a Web service (that is, it may express policy and require security tokens itself).
The typical message flow is as follows:
- The client sends a SOAP message to the Web service.
- The Web service has a policy that requires a token. Upon receiving the request, the service checks if it has a security token. If the token is absent, the Web service asks the client to obtain a token from a trusted STS.
- The client sends a security token request message to the STS in order to obtain the token.
- The STS examines the request and generates the requested token, sending it back to the client.
- The client resends the original message to the Web service, this time including the obtained token.
- The Web service receives the message, extracts the token and then send a validate message to the STS in order to get the token validated.
- The STS validates the token ands sends a validation status back to the Web service.
- If the token is valid, the Web service proceed with the invocation.
It is important to note that this is the most basic scenario in terms of trust relationships. As the STS is also a Web service, it can too have a policy that requires security tokens to be presented by clients. In this case, the client may need to obtain a different token from a second STS, and this STS may in turn require a token from a third STS and so on, creating much more complex trust relationships.
In this section we present the JBoss Security Token Service. As the name suggests, it is an implementation of the WS-Trust Security Token Service. The JBoss STS does not issue tokens of a specific type. Instead, it defines generic interfaces that allows multiple token providers to be plugged. As a result, it can be configured to deal with various types of token, as long as a token provider exists for each token type.
The overall architecture of the JBoss Security Token Service is illustrated in the figure bellow:
Let's give a quick description of the classes shown by the diagram:
- JBossSTS: it's the STS Web service, the component that is called by clients who want to request a security token. It implements the SecurityTokenService interface, which in turn extends the javax.xml.ws.Provider interface. The only method defined by the SecurityTokenService interface is public Source invoke(Source request). A Source object allows for generic XML source to be transmitted to the Web service - in this case, a WS-Trust request message.
- WSTrustJAXBFactory: utility class that is used by the JBossSTS to parse security token requests (i.e. convert between the XML request message and the JAXB object model) and marshall security token responses (i.e. convert the response JAXB objects to the XML response message that will be returned.
- STSConfiguration: this object is constructed by the JBossSTS and contains all the configurations defined by the STS administrator. Information like the default token timeout value, default request handler, the token provider that can handle a specific token type, are all supplied by this class. The concrete implementation is the JBossSTSConfiguration.
- WSTrustRequestHandler: instances of this interface are responsible for actually handling the WS-Trust requests. When a token request arrives, the JBossSTS parses the request message and delegates the request handling to the WSTrustRequestHandler instance that has been configured. After being created, the request handler instance is given a reference to the STSConfiguration in the public void initialize(STSConfiguration config) method. It uses the configuration to find out which security token provider should be used to handle the token request and also to set the default values for properties that are absent in the WS-Trust request message.
- WSTrustRequestContext: this class represents the security token request context. It contains all information that is relevant to the request processing. It also has a securityToken property that is used by the token providers to store the issued tokens.
- SecurityTokenProvider: a security token provider is responsible for handling the requests for a specific token type using the information contained in the supplied WSTrustRequestContext. The token providers are plugged into the STS via configuration.
In a nutshell, the security token request processing happens as follows:
- A client sends a security token request to JBossSTS.
- JBossSTS parses the request message, generating a JAXB object model.
- JBossSTS reads the configuration file and creates the STSConfiguration object, if needed. Then it obtains a reference to the WSTrustRequestHandler from the configuration and delegates the request processing to the handler instance.
- The request handler uses the STSConfiguration to set default values when needed (for example, when the request doesn't specify a token lifetime value).
- The WSTrustRequestHandler creates the WSTrustRequestContext, setting the JAXB request object and the caller principal it received from JBossSTS.
- The WSTrustRequestHandler uses the STSConfiguration to get the SecurityTokenProvider that must be used to process the request based on the type of the token that is being requested. Then it invokes the provider, passing the constructed WSTrustRequestContext as a parameter.
- The SecurityTokenProvider instance process the token request and stores the issued token in the request context.
- The WSTrustRequestHandler obtains the token from the context, encrypts it if needed, and constructs the WS-Trust response object containing the security token.
- The JBossSTS marshalls the response generated by the request handler and returns it to the client.
It is important to note that many different entities can act as a JBoss STS client. A client could be just a regular Web service client who needs to obtain or renew a security token in order to access the service, but it could also be the Web service itself trying to validate or cancel a token it has received.
Configuring JBoss STS
In the previous section we saw that JBoss STS defines several interfaces that provide extension points where implementations can be plugged via configuration. We also saw that default values for some properties can be specified via configuration. This leads to a couple of questions: What configuration options are available? Where do I configure JBoss STS?
In this section we show how to configure JBoss STS with the aid of an example. So we start with a sample configuration file:
<JBossSTS xmlns="urn:jboss:identity-federation:config:1.0" STSName="JBossSTS" TokenTimeout="7200" EncryptToken="true"> <KeyProvider ClassName="org.jboss.identity.federation.bindings.tomcat.KeyStoreKeyManager"> <Auth Key="KeyStoreURL" Value="keystore/sts_keystore.jks"/> <Auth Key="KeyStorePass" Value="testpass"/> <Auth Key="SigningKeyAlias" Value="sts"/> <Auth Key="SigningKeyPass" Value="keypass"/> <ValidatingAlias Key="http://services.testcorp.org/provider1" Value="service1"/> <ValidatingAlias Key="http://services.testcorp.org/provider2" Value="service2"/> </KeyProvider> <RequestHandler> org.jboss.identity.federation.api.wstrust.StandardRequestHandler </RequestHandler> <TokenProviders> <TokenProvider ProviderClass="org.jboss.test.identity.federation.bindings.trust.SpecialTokenProvider" TokenType="http://www.tokens.org/SpecialToken"/> <TokenProvider ProviderClass="org.jboss.test.identity.federation.bindings.trust.StandardTokenProvider" TokenType="http://www.tokens.org/StandardToken"/> </TokenProviders> <ServiceProviders> <ServiceProvider Endpoint="http://services.testcorp.org/provider1" TokenType="http://www.tokens.org/SpecialToken"/> <ServiceProvider Endpoint="http://services.testcorp.org/provider2" TokenType="http://www.tokens.org/StandardToken"/> </ServiceProviders> </JBossSTS>
All JBoss STS configurations must be specified in the jboss-sts.xml file. A breakdown of the configuration elements is provided bellow:
- JBossSTS: the root element. It defines some properties that allows the STS administrator to set a few default values:
- STSName: a String representing the name of the security token service. If not specified, the default JBossSTS value is used.
- TokenTimeout: the token lifetime value in seconds. If not specified, the default value of 3600 (1 hour) is used
- EncryptToken: a boolean specifying whether issued tokens must be encripted or not. The default value is false.
- KeyProvider: this element and all its subelements are used to configure the keystore that will be used by JBoss STS to sign and encrypt tokens. Properties like the keystore location, its password, and the signing (private key) alias and password are all configured in this section.
- RequestHandler: this element specifies the fully-qualified name of the WSTrustRequestHandler implementation to be used. If not specified the default org.jboss.identity.federation.api.wstrust.StandardRequestHandler is used.
- TokenProviders: this section specifies the SecurityTokenProvider implementations that must be used to handle each type of security token. In the example we have two providers - one that handles tokens of type SpecialToken and one that handles tokens of type StandardToken.
- ServiceProviders: this section specifies the token types that must be used for each service provider (the Web service that requires a security token). When a WS-Trust request doesn't contain the token type, the WSTrustRequestHandler must use the service provider endpoint to find out the type of the token that must be issued.
Having seen the elements and what they specify, the question now is where and how is all of this used?
- TokenTimeout is used by the WSTrustRequestHandler when no Lifetime has been specified in the WS-Trust request. It creates a Lifetime instance that has the current time as the creation time and expires after the specified number of seconds.
- EncryptToken is used by the WSTrustRequestHandler to decide if the issued token must be encrypted or not. If true, the public key certificate (PKC) of the service provider is used to encrypt the token.
- KeyProvider is used by the JBossSTSConfiguration to access the configured keystore and provide the STS signing key (private key) and the PKCs of the service providers to the WSTrustRequestHandler when it needs to sign or encrypt a security token.
- TokenProviders is used by the JBossSTSConfiguration to obtain the SecurityTokenProvider that must be used to handle a WS-Trust request that specifies the token type. The WSTrustRequestHandler calls the getProviderForTokenType(String type)method of STSConfiguration to obtain a reference to the appropriate SecurityTokenProvider.
- ServiceProviders is used by the JBossSTSConfiguration to obtain the SecurityTokenProvider that must be used to handle a WS-Trust request that doesn't specify the token type. In this case, the request message must identify the service provider endpoint. The JBossSTSConfiguration first locates the token type of the service provider using the mappings defined in this element, and then locates the SecurityTokenProvider using the TokenProviders mappings. The WSTrustRequestHandler calls the getProviderForService(String endpoint)method of STSConfiguration to obtain a reference to the appropriate SecurityTokenProvider.
NOTE 1: in this text, a service provider refers to the Web service that requires a security token to be presented by its clients.
NOTE 2: the example shows a configuration example that defines providers for custom token types (such as SpecialToken). For a list of standard token types, see the token profiles specified by OASIS.
Deploying JBoss STS
This section describes the steps to package, secure and deploy JBoss STS.
Sample Client Application
In this section we show an example of a client application that invokes JBoss STS to get a custom token.