Wednesday, November 2, 2011

Apache CXF STS documentation - part V

In the previous couple of posts (here and here) I detailed the TokenProvider interface, which is used to generate tokens in the STS, as well as two implementations that ship with the STS to generate SecurityContextTokens and SAML Tokens. In this post I will describe the interface that is used for validating tokens, as well as two implementations that ship with the STS, which are used to validate SecurityContextTokens, and (X.509) BinarySecurityTokens. In the next post, I will detail implementations which can validate a UsernameToken and a SAML Token. 

1) The TokenValidator interface

SecurityTokens are validated in the STS via the TokenValidator interface. It is very similar to the TokenProvider interface (hence some duplication of documentation from previous blog entries on the TokenProvider). It has three methods:
  • boolean canHandleToken(ReceivedToken validateTarget) - Whether this TokenValidator implementation can validate the given token
  • boolean canHandleToken(ReceivedToken validateTarget, String realm) - Whether this TokenValidator implementation can validate the given token in the given realm
  • TokenValidatorResponse validateToken(TokenValidatorParameters tokenParameters) - Validate a token using the given parameters.
A client can validate a security token via the STS by invoking the "validate" operation. Assuming that the client request is authenticated and well-formed, the STS will iterate through a list of TokenValidator implementations to see if they can "handle" the received token. If they can, then the implementation is used to validate the received security token, and the validation result is returned to the client. The second "canHandleToken" method which also takes a "realm" parameter will be covered in a future post.

So to support the validation of a particular token type in an STS deployment, it is necessary to specify a TokenValidator implementation that can handle that token. The STS currently ships with four TokenValidator  implementations, to validate SecurityContextTokens, SAML Assertions, UsernameTokens, and BinarySecurityTokens. Before we look at these implementations, let's take a look at the "validateToken" operation in more detail. This method takes a TokenValidatorParameters instance.

2) TokenValidatorParameters

The TokenValidatorParameters class is nothing more than a collection of configuration properties to use in validating the token, which are populated by the STS operations using information collated from the request, or static configuration, etc. The properties of the TokenValidatorParameters are:
  • STSPropertiesMBean stsProperties - A configuration MBean that holds the configuration for the STS as a whole.
  • Principal principal - The current client Principal object
  • WebServiceContext webServiceContext - The current web service context object. This allows access to the client request.
  • KeyRequirements keyRequirements - A set of configuration properties relating to keys. This will be covered later.
  • TokenRequirements tokenRequirements - A set of configuration properties relating to the token. This will be covered later.
  • STSTokenStore tokenStore - A cache used to retrieve tokens.
  • String realm - The realm to validate the token in (this should be the same as the realm passed to "canHandleToken"). This will be covered later.
If this looks complicated then remember that the STS will take care of populating all of these properties from the request and some additional configuration. You only need to worry about the TokenValidatorParameters object if you are creating your own TokenValidator implementation.

3) TokenValidatorResponse

The "validateToken" method returns an object of type TokenValidatorResponse. Similar to the TokenValidatorParameters object, this just holds a collection of objects that is parsed by the STS operation to construct a response to the client. The properties are:
  • boolean valid - Whether the token is valid or not.
  • Principal principal - A principal corresponding to the validated token.
  • Map<String, Object> additionalProperties - Any additional properties associated with the validated token.
  • String realm - The realm of the validated token.
4) The SCTValidator

Now that we've covered the TokenValidator interface, let's look at an implementation that is shipped with the STS. The SCTValidator is used to validate a token known as a SecurityContextToken, that is defined in the WS-SecureConversation specification. The SCTProvider was covered in a previous post. A SecurityContextToken essentially consists of a String Identifier which is associated with a particular secret key. If a service provider receives a SOAP message with a digital signature which refers to a SecurityContextToken in the KeyInfo of the signature, then the service provider knows that it must somehow obtain a secret key associated with that particular Identifier to verify the signature.

One way to do this would be if the service provider shares a (secured) distributed cache with an STS instance. An alternative solution would be for the service provider to send the SCT to an STS for validation, and to receive a SAML token in response with the embedded (encrypted) secret key. The SCTValidator can accommodate this latter scenario, albeit indirectly as will be explained shortly.

The SCTValidator can validate a SecurityContextToken in either of the following namespaces:
The SCTValidator validates a received SecurityContextToken by checking to see whether it is stored in the cache. Therefore it is a requirement to configure a cache for the STS if you want to validate SecurityContextTokens. If the SecurityContextToken is stored in the cache (for example, by the SCTProvider), then the received SecurityToken is taken to be valid. The secret associated with the SecurityContextToken is also retrieved from the cache, and set as an "additional property" in the TokenValidatorResponse using the key "sct-validator-secret". If the cached token has a stored principal, then this is also returned in the TokenValidatorResponse.

If you want to support the scenario of returning the secret key associated with the SecurityContextToken to the client (of the STS), then it is possible to do so via token transformation. This is where the client sends an additional Token Type (in this case for a SAML Token). After the token is validated, the SAMLTokenProvider is called with the additional properties map obtained from the SCTValidator. The SAMLTokenProvider then has access to the secret key via the "sct-validator-secret" tag, which it can insert into the Assertion using a custom AttributeProvider. Token Transformation will be covered in more detail in a future post.

5) The X509TokenValidator

Another TokenValidator implementation that ships with the STS is the X509TokenValidator. This class validates an X.509 V.3 certificate (received as a BinarySecurityToken). The BinarySecurityToken must use Base-64 encoding.
The received cert must be known (or trusted) by the STS crypto object, that is set on the STSPropertiesMBean object. The X509TokenValidator has a single property that can be configured:
  • void setValidator(Validator validator) - Set the WSS4J Validator instance to use to validate the received certificate. The default is SignatureTrustValidator.
No proof-of-possession is done with the received certificate. The subject principal of the certificate is set on the response, if validation is successful. Note that no caching is used in this TokenValidator implementation.

No comments:

Post a Comment