Colm O hEigeartaigh

Transforming Claims and Tokens in the CXF STS

Colm O hEigeartaigh - Wed, 06/06/2012 - 16:07
The Security Token Service (STS) shipped with Apache CXF 2.6.0 contains some advanced functionality relating to handling claims, as well as transforming both claims and security tokens.

1) ClaimsValue support

The following article describes in detail how Claims are handled by the STS. The client includes a Claims element in the request to the STS, which typically contains one or more ClaimType URIs, that describe the types of claims that are to be included in the issued token. For example, the following element indicates that the client wants the STS to embed the role of the authenticated client in the issued token:

<t:Claims Dialect="http://.../identity">
    <ic:ClaimType Uri="http://.../claims/role"/>
</t:Claims>

The RequestParser object parses the client request and converts a received Claims element into a RequestClaimCollection object. The RequestClaimCollection is just a list of RequestClaim objects, along with a dialect URI. The RequestClaim object holds the claimType URI as well as a boolean indicating whether the claim is optional or not. Since the 2.6.0 (and 2.5.3) release, the RequestClaim object now also holds a claimValue String. This means that the STS now supports processing a Claims element with ClaimValue elements rather than ClaimType elements, e.g.:

<t:Claims Dialect="http://.../identity">
    <ic:ClaimValue Uri="http://.../claims/role">
        <ic:Value>admin</ic:Value>
    </ic:ClaimValue>
</t:Claims>

2) Custom Claims Parsing

Prior to CXF 2.5.3 and 2.6.0, it was not possible to change how the RequestParser parses a received Claims child element into a RequestClaim object. In CXF 2.5.3 and 2.6.0 this behaviour is configurable. The ClaimsParser interface defines a method to parse a Claims child element, as well as return the supported dialect URI that the implementation can handle. CXF ships with a default implementation that handles the "http://schemas.xmlsoap.org/ws/2005/05/identity" URI, and can parse both ClaimType and ClaimValue elements.

The RequestParser is passed a list of ClaimsParser objects, and iterates through the list to find a ClaimsParser implementation that can handle the given dialect. It uses the first ClaimsParser implementation that matches the supported dialect to generate a RequestClaim object. Therefore, to support a custom or non-standard Claims dialect, it is necessary to implement one or more ClaimsParser implementations to handle that dialect. These ClaimsParser objects must then be set on the ClaimsManager.

3) Token and Claims Transformation

The following blog article describes how token transformation works in the STS prior to CXF 2.5.3 and 2.6.0. Token transformation occurs when the user calls the WS-Trust Validate binding to validate a given token. If the token is valid, and if the user specifies a TokenType that differs from the type of the given token, the STS will attempt to transform the validated token into a token of the requested type. If the token is being issued in a different realm to that of the validated token, the principal associated with the validated token may also need to be transformed. This can be done by specifying an IdentityMapper object on the STSPropertiesMBean object used to configure the STS. This interface is used to map identities across realms. It has a single method:
  • Principal mapPrincipal(String sourceRealm, Principal sourcePrincipal, String targetRealm) - Map a principal from a source realm to a target realm
If the source realm is not null (the realm of the validated token as returned in TokenValidatorResponse), and if it does not equal the target realm (as set by the RealmParser), then the identity mapper is used to map the principal to the target realm and this is stored in TokenProviderParameters for use in token generation.

3.1) Transformation via Relationships

The logic for token transformation as described above is abstracted in CXF 2.5.3 and 2.6.0 to add the ability to perform more powerful and custom token and claim transformations. Two new properties are added to the STSPropertiesMBean object:
  • List<Relationship> getRelationships() - Get the list of Relationship objects to use.
  • RelationshipResolver getRelationshipResolver() - Get the RelationshipResolver object to use.
The Relationship class holds the parameters that will be required to define
a one-way relationship between a source and target realm. It consists of five properties:
  • String sourceRealm - The source realm of this relationship.
  • String targetRealm - The target realm of this relationship.
  • IdentityMapper identityMapper - The IdentityMapper to use to map a principal from the source realm to the target realm.
  • ClaimsMapper claimsMapper - The ClaimsMapper to use to map claims from the source realm to the target realm.
  • String type - The relationship type. Two types of relationships are supported: FederatedIdentity and FederatedClaims.
The RelationshipResolver is instantiated with a list of Relationship objects and contains the following method:
  • Relationship resolveRelationship(String sourceRealm, String targetRealm) - Retrieve the Relationship object that maps from the given source realm to the given target realm. 
3.2) Principal Transformation using Relationships

The logic described above for transforming principals when doing token transformation is still valid, but is deprecated in favour of using Relationships. When the token is being issued in a different realm to that of the validated token, the STS will first try to retrieve a RelationshipResolver object from the STSPropertiesMBean. If it exists, it will query it to retrieve a Relationship object that can map claims and principals from the source realm to the target realm. If it finds a match it will store this object on the token provider parameters, so the TokenProvider implementation can use this RelationshipResolver to perform some internal or custom mapping when generating the transformed token.

If the type of the Relationship object matches the FederatedIdentity type, then the STS will try to retrieve an IdentityMapper object to map the principal from the Relationship object. Failing this it will try to query the STSPropertiesMBean object for a generic IdentityMapper object if one is configured. This IdentityMapper object will be used to map the principal to the target realm. 

3.4) Claims Transformation using Relationships

If the type of the Relationship object retrieved above is "FederatedClaims", then the principal is not mapped, as claims are transformed at the time when the claims are required to create a token, e.g. in ClaimsAttributeStatementProvider.



Categories: Colm O hEigeartaigh

Apache WSS4J 1.6.6 released

Colm O hEigeartaigh - Mon, 05/28/2012 - 18:16
Apache WSS4J 1.6.6 has been released and is available for download. WSS4J 1.6.6 contains an upgrade to use XML Security 1.5.2, the features of which are covered in a previous blog entry. Some significant fixes in the new release include:
  • Support for a configurable clock skew setting when processing the "NotBefore" timestamp associated with a SAML Token. 
  • Extending the maximum Time-To-Live setting associated with validating a Timestamp from the old value of 25 days.
  • Support for populating SubjectConfirmationData attributes of a SAML Assertion.
  • Support for a wider range of AuthenticationMethod values for SAML 1.1 Assertions.
Categories: Colm O hEigeartaigh

Apache XML Security for Java 1.4.7 and 1.5.2 released

Colm O hEigeartaigh - Wed, 05/16/2012 - 17:12
There are two new releases for the Apache XML Security for Java project, which are now available for download. The main feature of the 1.5.2 release is that the default canonicalization algorithm for encryption has changed from inclusive with comments to a new canonicalization algorithm that preserves the physical representation of the element being encrypted. This change fixes a problem where an element might be decrypted to the wrong namespace. The release notes are available here.

The 1.4.7 release fixes a problem with a missing KeyInfo Element when multiple elements are encrypted, as well as a number of other issues. The release notes are available here.
Categories: Colm O hEigeartaigh

Batch processing in the Apache CXF STS

Colm O hEigeartaigh - Fri, 04/27/2012 - 16:56
A previous blog entry covered the ability to renew SAML Tokens in the Security Token Service (STS) in Apache CXF 2.6.0. In this post, we will look at another major new feature in the STS in CXF 2.6.0, namely the addition of batch processing. Batch processing gives the ability to issue, validate, renew or cancel multiple tokens at the same time.

1) Batch Processing in the STS Provider framework

The STS implementation in CXF is based on the STS Provider framework in the security runtime, which is essentially an API that can be used to create your own STS implementation. The SEI (Service Endpoint Implementation) contains the following method that can be used for batch processing:
  • RequestSecurityTokenResponseCollectionType requestCollection(RequestSecurityTokenCollectionType requestCollection)
This method can be used to execute batch processing for any of the core operations (issue/validate/renew/cancel). To do this it is necessary to implement the RequestCollectionOperation interface, and to install it in the STS Provider.

2) Batch Processing in the STS implementation

The STS ships with an implementation of the RequestCollectionOperation interface described above that can be used to perform batch processing. The TokenRequestCollectionOperation is essentially a wrapper for the other operations, and does no processing itself. It iterates through the request collection that was received, and checks that each request has the same RequestType. If not then an exception is thrown. It then dispatches each request to the appropriate operation. To support bulk processing for each individual operation, it is necessary to set the appropriate implementation for that operation on the TokenRequestCollectionOperation, otherwise an exception will be thrown.

3) Batch Processing example

Take a look at the following test to see how batch processing works in practice. In this test, the client requests two tokens via the (batch) issue binding, a SAML 1.1 and a SAML 2.0 token. The client then validates both tokens at the same time using the batch validate binding. The STSClient class used by the WS-Security runtime in CXF does not currently support bulk processing. Therefore, the test uses a custom STSClient implementation for this purpose.

The WSDL the STS uses two separate bindings for issue and validate, to cater for the fact that two separate SOAP Actions must be used for bulk issue and validate for the same operation. The STS configuration is available here. Note that the TokenRequestCollectionOperation is composed with the TokenIssueOperation and TokenValidateOperation, to be able to bulk issue and validate security tokens:
<bean class="org.apache.cxf.sts.operation.TokenRequestCollectionOperation"
id="transportRequestCollectionDelegate">
<property name="issueSingleOperation" ref="transportIssueDelegate">
<property name="validateOperation" ref="transportValidateDelegate>
</bean>

Categories: Colm O hEigeartaigh

Security Token Caching in Apache CXF 2.6 - part II

Colm O hEigeartaigh - Wed, 04/25/2012 - 17:37
This post is the second in a two-part series on how security tokens are cached in Apache CXF 2.6. Part I covered how UsernameToken nonces and Timestamps are cached to prevent replay attacks, using a default caching implementation based on EhCache. In this post I will cover how security tokens are cached in the CXF WS-Security runtime and also in the STS.

1) CXF WS-Security runtime token caching

CXF caches tokens in the security runtime in the following circumstances:
  • When the IssuedTokenInterceptorProvider is invoked to obtain an Issued token from an STS.
  • When the STSTokenValidator is used to validate a received UsernameToken, BinarySecurityToken or SAML Assertion to an STS.
  • When the SecureConversation protocol is used.
  • When the WS-Trust SPNEGO protocol is used.
  • When tokens are obtained from a Kerberos KDC.
In each of these use-cases, the retrieved token is cached to prevent repeated remote calls to obtain the desired security token. There is no built-in support as yet to cache tokens in the WS-Security layer to prevent repeat validation. Of course this could be easily done by wrapping the existing validators with a custom caching solution.

1.1) SecurityTokens

CXF defines a SecurityToken class which encapsulates all relevant information about a successful authentication event in the security runtime (as defined above). In particular, it contains the following items (amongst others):
  • A String identifier of the token. This could be a SAML Assertion Id, the Identifier element of a SecurityContextToken, or the wsu:Id of a UsernameToken, etc.
  • The DOM Element that represents that security token.
  • Attached and Unattached reference elements for that token that might have been retrieved from an STS.
  • A byte[] secret associated with the token.
  • An expiration date after which the token is not valid.
  • A String TokenType that categorizes the token.
  • An X.509 Certificate associated with the token.
  • The principal associated with the token.
  • A hashcode that represents the security token (normally the hashcode of the underlying WSS4J object).
  • An identifier of another SecurityToken that represents a transformed version of this token.
 1.2) TokenStores

CXF defines a TokenStore interface for caching SecurityTokens in the WS-Security runtime module. Prior to CXF 2.6, a simple default HashMap based approach was used to cache security tokens. In CXF 2.6, Ehcache is used to provide a suitable default TokenStore implementation to cache security tokens. Tokens are stored until the expiry date of the token if it exists, provided it does not exceed the maximum storage time of 12 hours. If it exceeds this, or if there is no expiry date provided in the security token, it is cached for the default storage time of 1 hour. If the token is expired then it is not cached. This default storage time is configurable. Note that while Ehcache is a compile time dependency of the WS-Security module in CXF, it can be safely excluded in which case CXF will fall back to use the simple HashMap based cache, unless the user specifically wants to implement an alternative TokenStore implementation and configure this instead.

Apache CXF 2.6 provides support for configuring caching via the following JAX-WS properties:
  • "org.apache.cxf.ws.security.tokenstore.TokenStore" - The TokenStore instance to use to cache security tokens. By default this uses the EHCacheTokenStore if Ehcache is available. Otherwise it uses the MemoryTokenStore.
  • "ws-security.cache.config.file" - Set this property to point to a configuration file for the underlying caching implementation. By default the cxf-ehcache.xml file in the CXF rt-ws-security module is used.
2) CXF STS token caching

Token caching in the CXF STS has been previously (briefly) covered in the STS documentation. Prior to CXF 2.6, the STS shipped an interface called "STSTokenStore" that contained some additional functionality related to storing SecurityTokens specific to the STS. In CXF 2.6, this interface has been removed, and instead the same TokenStore interface is used as in the security runtime. A TokenStore instance can be set on any of the STS operations (see AbstractOperation), and it will be used for caching in the token providers, validators, etc. The STS ships with two TokenStore implementations, a DefaultInMemoryTokenStore which just wraps the EHCacheTokenStore discussed above, and an implementation based on HazelCast.

Token caching works in different ways depending on where it is used. Both token providers (SAML and SecurityContextTokens) that ship with the STS cache a successfully generated token. When a SAML or SecurityContextToken (or UsernameToken) is received by the STS for validation, it will first check to see whether the token is stored in the cache. If it is then validation is skipped. If it is not, then the TokenValidator will re-validate the token, and store it in the cache if validation is successful. A slight caveat to this behaviour for SAML Tokens is that token validation is only skipped if the token that is stored in the cache originally was signed, as this signature value is used to check to see if the two SAML Tokens are equal. The TokenCanceller implementation for cancelling SecurityContextTokens in the STS removes the token from the cache, if the token is stored in the cache and proof-of-possession passes.

Finally, two significant changes in CXF 2.6.0 concerning caching in the STS relate to the length of time tokens are valid for. Prior to CXF 2.6.0, SecurityContextTokens and SAML Tokens issued by the STS were valid for a default (configurable) value of 5 minutes. In CXF 2.6.0, both tokens are now issued for a default value of 30 minutes, and are stored in the cache for this length of time as a result.
Categories: Colm O hEigeartaigh

Note on CVE-2011-1096

Colm O hEigeartaigh - Mon, 04/23/2012 - 11:21
A new attack on the XML Encryption standard has recently emerged and is described by the security advisory CVE-2011-1096:
Tibor Jager, Juraj Somorovsky, Meiko Jensen, and Jorg Schwenk
described an attack technique against W3C XML Encryption Standard,
when the block ciphers were used in cipher-block chaining (CBC)
mode of operation. A remote attacker, aware of a cryptographic
weakness of the CBC mode could use this flaw to conduct
chosen-ciphertext attacks, leading to the recovery of the entire
plaintext of a particular cryptogram by examining of the differences
between SOAP responses, sent from JBossWS, J2EE Web Services server.There is no (immediate) security "fix" for this issue, as it is an attack on the standard itself. However, the attack can be prevented by using a symmetric algorithm such as AES-128 or AES-256 with GCM. Support for GCM algorithms is available in Apache Santuario 1.5.0 and Apache WSS4J 1.6.5 (see here).

One problem with using a GCM algorithm via WS-SecurityPolicy is that no AlgorithmSuite policy is defined in the WS-SecurityPolicy 1.3 specification that uses GCM. Until the WS-SecurityPolicy specification is updated to support GCM, Apache CXF has defined its own AlgorithmSuite policies to use GCM algorithms. These AlgorithmSuites are called "Basic128GCM", "Basic192GCM" and "Basic256GCM" in the namespace "http://cxf.apache.org/custom/security-policy", and are exactly the same as the corresponding standard "Basic(128|192|256)" policies, except that GCM is used instead of CBC. For example, to use the AES-128 Algorithm with GCM mode, one would use a policy like:

<sp:AlgorithmSuite>
    <wsp:Policy>
        <sp-cxf:Basic128GCM xmlns:sp-cxf="http://cxf.apache.org/custom/security-policy"/>
    </wsp:Policy>
</sp:AlgorithmSuite>

CXF contains a number of system tests that show how to use these new AlgorithmSuites. The WSDL containing the embedded policies is here, and the test itself is here. This functionality is available from Apache CXF 2.4.7, 2.5.3, and 2.6.0.

In addition to this, the CXF JAX-RS XML Security functionality has been updated so that GCM algorithms can be used for encryption and decryption via the BouncyCastle JCE provider. A test is available here. For more information on the CXF JAX-RS XML Security functionality, checkout Sergey's blog or the CXF wiki page.
Categories: Colm O hEigeartaigh

Renewing SAML Tokens in the Apache CXF STS

Colm O hEigeartaigh - Fri, 04/20/2012 - 13:36
Apache CXF 2.6.0 sees a number of improvements to the functionality of the SecurityTokenService (STS). These include relatively minor tasks such as supporting SymmetricKeys for Entropy and BinarySecret Elements, supporting SecurityTokenReferences in UseKey Elements, and supporting KeyInfo/KeyValue Elements in UseKey Elements. However, the STS also includes two major new features. The first of these new features, the ability to renew (SAML) tokens, is covered in this blog entry.

1) The TokenRenewer interface

Security tokens are renewed in the STS via the TokenRenewer interface. It has the following methods:
  • void setVerifyProofOfPossession(boolean verifyProofOfPossession) - A boolean switch to enable or disable the proof of possession requirement.
  • void setAllowRenewalAfterExpiry(boolean allowRenewalAfterExpiry) - A switch to enable or disable the ability to renew tokens after they have expired.
  • boolean canHandleToken(ReceivedToken renewTarget) - Whether this TokenRenewer implementation can renew the given token.
  • boolean canHandleToken(ReceivedToken renewTarget, String realm) - Whether this TokenRenewer implementation can renew the given token in the given realm.
  • TokenRenewerResponse renewToken(TokenRenewerParameters tokenParameters) - Renew the token using the given parameters
A client can request that the STS renew a security token by invoking the "renew" operation and supplying a token under the "RenewTarget" Element. Assuming that the client request is authenticated and well-formed, the STS will first 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. If no TokenValidator is found that can handle the RenewTarget that was received, then an exception is thrown. Note that this means that for token renewal, it is necessary to configure both a TokenValidator and TokenRenewer implementation that can handle the given token.

After the successful validation of a token, the state of the token is checked. If the state is not valid or expired, then an exception is thrown. The STS then iterates through the configured list of TokenRenewer implementations to see which can renew the given (validated) token. The token is then renewed and returned to the client.

The TokenRenewerParameters class is nothing more than a collection of configuration properties to use in renewing the token, which are populated by the STS operations using information collated from the request, or static configuration, etc. The TokenRenewerResponse class holds the results from the (successful) token renewal, including the DOM representation of the renewed token, the token Id, the new lifetime of the renewed token, and references to the renewed token. 

2) The SAMLTokenRenewer

The SAMLTokenRenewer can renew valid or expired SAML 1.1 and SAML 2.0 tokens. The following properties can be configured on the SAMLTokenRenewer directly:
  • boolean signToken - Whether to sign the renewed token or not. The default is true.
  • ConditionsProvider conditionsProvider - An object used to add a Conditions statement to the token.
  • Map<String, SAMLRealm> realmMap - A map of realms to SAMLRealm objects. See here for an explanation of realms in the SAMLTokenProvider.
  • long maxExpiry - how long a token is allowed to be expired (in seconds) before renewal. The default is 30 minutes.
The SAMLTokenRenewer first checks that the token it extracts from the TokenRenewerParameters is in an expired or valid state, if not it throws an exception. It then retrieves the cached token that corresponds to the token to be renewed. A cache must be configured to use the SAMLTokenRenewer, and the token to be renewed must be in the cache before renewal takes place, for reasons that will become clear in the next section.

2.1) Token validation

Before the received SAML token can be renewed, a number of validation steps (that are specific to renewing SAML tokens) takes place. Two boolean properties are retrieved from the properties of the cached token:
  • org.apache.cxf.sts.token.renewing.allow - Whether the token is allowed to be renewed or not.
  • org.apache.cxf.sts.token.renewing.allow.after.expiry - Whether the token is allowed to be renewed or not after it has expired.
These two properties are set in the SAMLTokenProvider based on a received "<wst:Renewing/>" element when the user is requesting a SAML token via the issue binding. If a user omits a "<wst:Renewing/>" element, or sends "<wst:Renewing/>" or "<wst:Renewing Allow="true"/>", then the token is allowed to be renewed. However, only if the user sends <wst:Renewing OK=True"/>", will the token be allowed to be renewed after expiry. This explains why a TokenStore is required for token renewal, as without access to these two properties it is impossible for the SAMLTokenRenewer to figure out whether the issuer of the token intended for the token to be renewed (after expiry) or not.

If the state of the token is expired, and if the token is allowed to be renewed after expiry, a final check is done against the boolean set via the "setAllowRenewalAfterExpiry" method of TokenRenewer. If this is set to false (the default), then an exception is thrown. So to support token renewal after expiry, you must explicitly define this behaviour on the TokenRenewer implementation. Finally, a check is done on how long ago the SAML Token expired. If it is greater than the value configured in the "maxExpiry" property (30 minutes by default), then an exception is thrown.

The next validation step is to check proof of possession, if this is enabled (true by default). The Subject KeyInfo of the Assertion must contain a PublicKey or X509Certificate that corresponds to either the client certificate if TLS is used, or to the private key that was used to sign some part of the request. Finally, if an "AppliesTo" URI is sent as part of the request, the SAMLTokenRenewer checks that the received Assertion contains at least one AudienceRestrictionURI that matches that address, otherwise it throws an Exception.

2.2) Renewing the SAML Assertion

After the validation steps outlined above have passed, the token is renewed in the following way:
  • A new ID is generated for the token.
  • A new "IssueInstant" is set on the token.
  • A new Conditions Element replaces the old Conditions Element of the token, using the configured ConditionsProvider.
  • The Assertion is (re)-signed if the "signToken" property is true.
The old token is removed from the cache, and the new token is added. Finally, the token is set on the TokenRenewerResponse, along with the token Id, and Lifetime.

3) SAML Token Renewal in action

Finally, let's take a look at a system test in CXF that shows how to renew a SAML Token issued by an STS. The wsdl of the service provider defines a number of endpoints which use the transport binding, with a (endorsing) supporting token requirement which has an IssuedToken policy that requires a SAML token. In other words, the client must request a SAML token from an STS and send it to the service provider over TLS, and optionally use the secret associated with the SAML token to sign the message Timestamp (if an EndorsingSupportingToken policy is specified in the wsdl).

The STS spring configuration is available here. The SAMLTokenRenewer is configured with proof-of-possession enabled, and tokens are allowed to be renewed after they have expired. Let's look at the test code and client configuration. All of the tests follow the same pattern. The client requests a SAML Token from the STS (as per the IssuedToken policy), with a TTL (time-to-live) value of 8 seconds. The client then uses this issued token to make a successful request to the service provider. The test code then sleeps for 8 seconds to expire the token, and tries to invoke on the service provider again. The IssuedTokenInterceptorProvider in the WS-Security runtime in CXF recognises that the token has expired, and sends it to the STS for renewal. The returned (renewed) token is then sent to the service provider.
Categories: Colm O hEigeartaigh

Security Token Caching in Apache CXF 2.6 - part I

Colm O hEigeartaigh - Wed, 04/18/2012 - 12:52
This post is the first of a two-part series on how security tokens are cached in Apache CXF 2.6.0, which has just been released. In this particular post I will examine how Apache CXF provides detection against replay attacks on the WS-Security protocol. Apache WSS4J 1.6.5 provides support for detecting and preventing replay attacks.

1) Replay attacks on the WS-Security protocol

A replay attack in this context is when an adversary intercepts a WS-Security enabled message and sends it again to the original intended target of the message. As the message is a direct copy of the original (presumably valid) message, the normal security processing steps should pass without error. Therefore, some additional steps are required on both the initiator and recipient side to protect against these attacks.

2) Message initiator requirements

The initiator should take either or both of the following steps:
  • If the initiator is including a UsernameToken in the message, the initiator should include a nonce in the UsernameToken. A nonce is a random String that can serve as an identifier for the message. The recipient can then cache this value for a certain time period and reject any subsequent message containing this nonce.
  • The initiator should include a Timestamp in the security header of the message. This step alone provides a certain protection against a replay attack if it includes an Expires element, which the recipient should reject if it contains a value prior to the time the message was received at. The Created value of the Timestamp can also serve as the basis of a unique identifier to store in a replay cache.
3) Message recipient requirements

A service provider that uses WS-SecurityPolicy can enforce the message requirements defined above on the client by doing the following:
  • Use a <sp:HashPassword/> OR a <sp13:Nonce/> policy in the UsernameToken policy.
  • Add a <sp:IncludeTimestamp/> to the binding policy.
In addition to this, the recipient must provide a cache to store the UsernameToken nonce values and Timestamp Created values. Note that Timestamp Created values do not provide enough "uniqueness" on their own, as the recipient could receive two valid messages from different clients that were created at the same millisecond in time. Therefore, WSS4J combines the Timestamp Created value with a message Signature value to form a unique identifier. If no message signature is included in the message, then no replay caching is done for Timestamps. However, note that CXF already enforces that a Timestamp must be signed for the Symmetric and Asymmetric WS-SecurityPolicy bindings.

4) Replay caching support in WSS4J

Apache WSS4J 1.6.5 provides support for detecting and preventing replay attacks by introducing the ReplayCache interface. A seperate ReplayCache instance is used to cache UsernameToken nonces and Timestamp Created / Signature Value Strings. WSS4J ships with a sample HashSet based implementation, which is not intended for production use. The default caching time for this implementation is 5 minutes - Timestamps are cached until their expiry time (if it exists), otherwise for 5 minutes.

The ReplayCache implementations to use can be configured via RequestData. No ReplayCache implementation is used by default for backwards compatibility reasons - to enable it you must implement the ReplayCache interface, and set the appropriate methods on RequestData. 

5) Replay caching support in CXF.

Apache CXF 2.6 uses Ehcache to provide a suitable ReplayCache implementation to detect replay attacks. The default cache time for the Ehcache implementation is 60 minutes. No configuration is required for out-of-the-box support for replay attack detection on the message recipient side. Caching is not enabled by default on the inbound initiator side for efficiency reasons. Note that this functionality is available in Apache CXF 2.4.7 and 2.5.3, but is not enabled by default at all for backwards-compatibility reasons. Ehcache is an optional provided dependency for these releases, meaning that you will have to include it as a dependency and enable caching to get replay caching to work. If caching is enabled and Ehcache is not available, then CXF will fall back to using the default HashSet based implementation that ships with WSS4J. Note that this is not intended for production use and will entail performance penalties.

Apache CXF 2.6 provides support for configuring replay caching via the following JAX-WS properties:
  • "ws-security.enable.nonce.cache" - The default value is "true" for message recipients, and "false" for message initiators. Set it to true to cache for both cases.
  • "ws-security.enable.timestamp.cache" - This uses the same logic as above.
  • "ws-security.nonce.cache.instance" - This holds a reference to a ReplayCache instance used to cache UsernameToken nonces. The default instance that is used is the EHCacheReplayCache.
  • "ws-security.timestamp.cache.instance" - This uses the same logic as above.
  • "ws-security.cache.config.file" - Set this property to point to a configuration file for the underlying caching implementation. By default the cxf-ehcache.xml file in the CXF rt-ws-security module is used.
Categories: Colm O hEigeartaigh

UsernameToken Derived Key support in Apache CXF

Colm O hEigeartaigh - Wed, 03/21/2012 - 17:23
Support for UsernameToken derived keys has been added to Apache CXF and will be available in the forthcoming 2.4.7 and 2.5.3 releases. UsernameTokens are usually used for authentication, where an initiator places a username and password (plaintext or digested) in the security header of a Soap request. However, it is also possible to exploit the fact that the initiator and recipient share a common secret (the password), by deriving a key from the UsernameToken to perform message level encryption or signature. This functionality provides an alternative to the usual certificate-based approach involved in message level security.

The WS-Security UsernameToken 1.1 profile describes how to derive keys from a UsernameToken. The UsernameToken does not include a password in this case, but includes Username, Salt and (an optional) Iteration elements. The Salt is a 128 bit value, where the high-order 8 bits have the value 01 when it is used for signature, and 02 when used for encryption. This implies that a key derived from a UsernameToken can be used for either signature or encryption, but not both. 

1) Running the UsernameToken derived key system tests in Apache CXF 

The best way to understand how to use this functionality is to take a look at the system tests. To run the UsernameToken derived key system tests in CXF, make sure that the JDK has unlimited security policies installed, and then checkout the CXF trunk via:
svn co https://svn.apache.org/repos/asf/cxf/trunk/Go into the "trunk" directory, and compile and install CXF via "mvn -Pfastinstall" (this will avoid running tests). Finally go into the WS-Security system tests in "systests/ws-security". The UsernameTokenDerivedTest contains a number of tests that show how to use keys derived from Username Tokens to secure a message exchange. The service and client endpoints are spring-loaded. If you want to see the message exchanges, open src/test/resources/logging.properties, and change the level from WARNING to INFO, and the ConsoleHandler level from SEVERE to INFO. Finally, run the tests via:

        mvn test -Dtest=UsernameTokenDerivedTest

2) WS-SecurityPolicy configuration

The wsdl that defines the service endpoints contains WS-SecurityPolicy expressions that define the security requirements of the endpoints. The following security policies are used for the tests:
  • DoubleItSymmetricProtectionPolicy: This uses a Symmetric binding, where the protection token is a UsernameToken. In other words, a key is derived from the UsernameToken according to the spec, and is used to encrypt or sign the message request.
  • DoubleItSymmetricProtectionDKPolicy: This is the same as above, except that instead of using the UsernameToken derived key directly, another derived key is used instead.
  • DoubleItSymmetricProtectionEncPolicy: This is the same policy as above, except that it is used for encryption and not signature. It does not include a Timestamp requirement, as this would require that the Timestamp be signed.
  • DoubleItTransportEndorsingPolicy: This uses a Transport binding, where a UsernameToken is included as an EndorsingSupportingToken. In other words, the key derived from the UsernameToken is used to sign the Timestamp.
  • DoubleItSymmetricSignedEndorsingPolicy: This uses a Symmetric binding, where a UsernameToken is included as a SignedEndorsingSupportingToken. 
  • DoubleItSymmetricEndorsingEncryptedPolicy: This uses a Symmetric binding, where a UsernameToken is included as a EndorsingEncryptedSupportingToken.
  • DoubleItSymmetricSignedEndorsingEncryptedPolicy: This uses a Symmetric binding, where a UsernameToken is included as a SignedEndorsingEncryptedSupportingToken. 
UsernameToken derived keys are not currently supported with the Asymmetric binding.
Categories: Colm O hEigeartaigh

Apache WSS4J 1.6.5 released

Colm O hEigeartaigh - Mon, 03/05/2012 - 12:32
Apache WSS4J 1.6.5 has been released. The list of issues that were fixed in this release is available here. This is quite a significant release as it contains an upgrade to use Apache Santuario (XML Security for Java) 1.5. This release is intended to be the last major development release on the 1.6.x branch. There are exciting plans for WSS4J 2.0 which I will describe shortly. Here is a summary of some of the main features of this release: 

1) Apache Santuario (XML Security for Java) 1.5.1 upgrade

WSS4J has upgraded the Santuario dependency from 1.4.6 to 1.5.1 and hence picks up the following relevant new features:
  • Support for GCM algorithms has been added via a third-party JCE provider (e.g. BouncyCastle). I will describe this in more detail in a future blog post.
  • Support for Key Transport Algorithms with strong digests is available.
  • More secure validation of incoming signed requests is performed.
  • Better protection against signature wrapping attacks is available.
For more information on the new features associated with Santuario 1.5.0 see here. WSS4J picks up Santuario 1.5.1 which fixes a number of important issues in the 1.5.0 release. 

2) Improvements in validating SAML Assertions

WSS4J contains the following improvements related to validating SAML Assertions:
  • Validation of SAML Condition NotBefore/NotOnOrAfter dates.
  • Validate the received Assertion against the schema/specs.
A bug has also been fixed when creating a SAML Token where the NotOnOrAfter Condition is not set correctly in some cases.  

3) Improvements relating to certificate revocation

There are a number of fixes relating to certificate revocation:
  • Revocation is not performed if the certificate is contained in the keystore.
  • Revocation is now supported before encryption on the sending side.
Categories: Colm O hEigeartaigh

Apache Santuario (XML Security for Java) 1.5.1 released

Colm O hEigeartaigh - Fri, 03/02/2012 - 11:28
Apache Santuario (XML Security for Java) 1.5.1 has been released and is available for download. The release notes are available here. This release fixes two important bugs - a bug in XMLSignatureInput when using a BufferedInputStream, as well as a bug which caused 1.5.0 to continue to require Xalan. It also contains some performance improvements for encryption and decryption.
Categories: Colm O hEigeartaigh

WS-Trust SPNego support in Apache CXF

Colm O hEigeartaigh - Wed, 02/22/2012 - 14:02
Support for SPNego using WS-Trust has been added to Apache CXF and will be available in the forthcoming 2.4.7 and 2.5.3 releases. This new functionality allows a CXF client to integrate with WCF 4.0, as WCF 4.0 uses message level NTLM/Kerberos based on SPNego using WS-Trust. See the following blog for an in-depth explanation of how to do exactly this. Support for obtaining and validating SPNEGO tokens was added to Apache WSS4J in the 1.6.4 release. WSS4J 1.6.5 will feature support for making the Spnego Client and Service Action classes pluggable, so that the user can specify a custom means of obtaining the ticket.

Using WS-Trust for SPNego is described in the following application note. The client contacts a KDC and obtains a SP Negotiation token, which it sends to the service provider via WS-Trust. If the negotiation is incomplete, the service provider can respond to the client to continue the negotiation. Once the negotiation is complete, a WS-Trust RequestedProofToken is created which contains a secret key that has been encrypted with the negotiated key, and this is returned to the client along with an Authenticator and a SecurityContextToken. The client can decrypt the EncryptedKey, and use this key with a symmetric encryption or signature algorithm to secure a request.

Note that the focus is on making sure that a CXF client can interoperate with WCF, and hence the STS support for SPNego is only intended as a means of testing the client code. In particular, the STS does not return an Authenticator, which is required by the spec. One additional limitation is that the STS client does not currently support continued negotation.

1) Running the WS-Trust SPNego system tests in Apache CXF 

To run the WS-Trust SPNego system tests in CXF, it is first necessary to set up a KDC correctly. Follow the instructions given in section 1 in a previous blog post which describes how to run the Kerberos system tests in CXF. Next, make sure that the JDK has unlimited security policies installed, and then checkout the CXF trunk via:
svn co https://svn.apache.org/repos/asf/cxf/trunk/Go into the "trunk" directory, and compile and install CXF via "mvn -Pfastinstall" (this will avoid running tests). Finally go into the WS-Security system tests in "systests/ws-security". The SpnegoTokenTest contains two tests, which are @Ignore'd by default. Open SpnegoTokenTest.java and comment out the "@org.junit.Ignore" entries for both tests. If you want to see the message exchanges, open src/test/resources/logging.properties, and change the level from WARNING to INFO, and the ConsoleHandler level from SEVERE to INFO. Finally, run the tests via:

        mvn test -Dtest=SpnegoTokenTest -Djava.security.auth.login.config=src/test/resources/kerberos.jaas

1.1) WS-SecurityPolicy configuration

The wsdl that defines the service endpoints contains WS-SecurityPolicy expressions that define the security requirements of the endpoints. The following security policies are used for the tests:
  • DoubleItSpnegoSymmetricProtectionPolicy: This uses a Symmetric binding, where the protection token is a SpnegoContextToken.
  • DoubleItSpnegoSymmetricProtectionDerivedPolicy: This uses a Symmetric binding, where the protection token is key derived from a SpnegoContextToken.
1.2) Kerberos LoginModule configuration

Both the CXF client and service endpoint use JAAS to authenticate to the KDC. The JAAS file used as part of the system test is passed to the tests via the System property "java.security.auth.login.config". The client (alice) uses the following login module:
alice {
    com.sun.security.auth.module.Krb5LoginModule required
    refreshKrb5Config=true useKeyTab=true keyTab="/etc/alice.keytab"
    principal="alice";
};and the service endpoint (bob) uses:
bob {
    com.sun.security.auth.module.Krb5LoginModule required
    refreshKrb5Config=true useKeyTab=true storeKey=true
    keyTab="/etc/bob.keytab" principal="bob/service.ws.apache.org";
}; 1.3) Client and Service endpoint configuration

Both the service and client endpoints are spring-loaded. The contain the following JAX-WS properties, which are defined in SecurityConstants:
  •  "ws-security.kerberos.jaas.context" - This refers to the JAAS context given in the configuration file above. The clients use a value of "alice", and the service endpoints use "bob".
  • "ws-security.kerberos.spn"- This is only configured on the client side, and specifies the Kerberos Service Provider Name ("bob@service.ws.apache.org").
Finally, there is one additional JAX-WS property that can be defined on the client, if you want to plug in a custom WSS4J SpnegoClientAction implementation:
  • "ws-security.spnego.client.action" - The SpnegoClientAction implementation to use for SPNEGO. This allows the user to plug in a different implementation to obtain a service ticket. See here for more details on how to use this property.
Categories: Colm O hEigeartaigh

Apache Santuario (XML Security for Java) 1.5.0 released

Colm O hEigeartaigh - Tue, 01/24/2012 - 16:51
Apache Santuario (XML Security for Java) 1.5.0 has been released. It can be downloaded here. Please read the release notes (collated from my previous blog entries) if you are planning to upgrade.
Categories: Colm O hEigeartaigh

Apache Santuario (XML Security for Java) 1.5.0 RC2

Colm O hEigeartaigh - Fri, 01/13/2012 - 17:52
I posted a RC1 for Apache Santuario (XML Security for Java) almost a month ago now. Since then, a large number of changes have been made to address some inconsistencies in RC1 as well to add some new functionality. The RC2 release is available here. Please download it and post any issues that are found to the mailing list. The changes compared to the RC1 release (documented here) are as follows:

1) Support for RSA-OAEP key transport algorithms with strong digests

The 1.4.x releases only support using SHA-1 with the RSA-OAEP key transport algorithm for encryption and decryption. The 1.5.0 RC2 release supports stronger digests using the ds:DigestMethod child of xenc:EncrytionMethod. In addition, it fully supports the xenc11:MGF Algorithm as documented in the XML Encryption 1.1 specification.

To test this functionality, all of the XML Encryption 1.1 Key Wrapping test-cases have been implemented, both for encryption and decryption. These tests also serve to better test the support for GCM algorithms in the 1.5.0 release. Support for 192 bit AES-GCM was added as part of this work. 

2) Major changes to how Elements are resolved

The release notes for RC1 described how the IdResolver no longer searches the current Document for an Element matching the requested Id in certain "known" namespaces, and instead how it was the responsibility of the user to register Elements by Id in the IdResolver (or via setIdAttributeNS if using the JSR-105 API), if they are required as part of the signature validation process.

In RC2, the static cache of Id->Elements that was maintained in the IdResolver has been removed. Instead, the ResourceResolver implementations that are responsible for resolving same-Document URI references resolve Elements by querying Document.getElementById(). The IdResolver has been deprecated, so that it is no longer possible to register an Element by Id, and the "get" methods simply delegate to the DOM call above.

So what does this mean for the user? The user is now responsible for registering any same-Document Elements by Id, which must be resolved as part of the signature creation/validation process. This can be done in two ways:
  1. Using the DOM APIs: Element.setIdAttribute*
  2. Using the JSR-105 API: DOMCryptoContext.setIdAttributeNS
3) Better protection against Signature Wrapping Attacks

A Signature Wrapping attack can occur when a malicious entity duplicates some signed Element in a document, and then modifies the content of the duplicated Element, but keeps the same Id. If the signature validation process only finds the initial Element, then signature validation will pass, and the user might be fooled into thinking that the modified Element has been signed, as it has the same Id as the original validated Element.

The implication of this attack is that it is vital that the user checks that the Elements that were signed correspond to the Elements that he/she expects to be signed. In other words, the Elements that were signed should be located in a specific "known" place in the Document. The best way of facilitating this check is to make sure that the signature validation process returns the Elements that it validated. The JSR-105 API supports this via the "javax.xml.crypto.dsig.cacheReference" boolean property, that can be set on the context.

However, the older XMLSignature, which pre-dates the JSR-105 API, did not include this functionality. This has been fixed in the RC2 release, e.g.:

XMLSignature signature = ...
// Perform validation and then...
SignedInfo signedInfo = signature.getSignedInfo();
for (int i = 0; i < signedInfo.getLength(); i++) {
    Reference reference = signedInfo.item(i);
    ReferenceData refData = reference.getReferenceData();
    ....
}

ReferenceData is a new interface that duplicates the way the JSR-105 API returns references. Three different implementations have been provided depending on whether the dereferenced Element is a NodeSet, Element or OctetStream.

Finally, some new functionality has been added when secure validation is enabled, to ensure that when an Element is de-referenced via Document.getElementById() (as described above), no other Element in the tree has an Attribute that is also registered as an Id with the same value. This is done via a tree search, and guarantees that the Element retrieved via the getElementById call is unique in the Document (something that is not guaranteed by the contract of getElementById). However note that another Element could still exist in the tree with a matching Id in another namespace.
Categories: Colm O hEigeartaigh

Apache CXF 2.5.1 STS updates

Colm O hEigeartaigh - Fri, 01/13/2012 - 15:25
Last year I wrote a series of blog posts (starting here) documenting the Security Token Service (STS) implementation included as part of Apache CXF 2.5.0. Apache CXF 2.5.1 was released a few weeks ago, and includes a number of bug fixes and improvements to the STS. In this post I'll document the more important changes.
 
1) Support to configure keystores per SAML realm
 
In CXF 2.5.0 it was possible to sign an issued SAML Token using a different private key per realm, by setting the "signatureAlias" property of the SAMLRealm class. However, the signature alias is used with a single KeyStore, which is shared across all realms. This problem has been fixed in CXF 2.5.1, where it is now possible to also configure a keystore to use per-realm.

2) Support to handle claims per realm
 
In CXF 2.5.1 support has been added to handle claims per-realm. The ClaimsHandler interface has been updated to so that the current realm and WebServiceContext object are available when retrieving claim values. This means that any custom ClaimsHandler implementation based on CXF 2.5.0 must be updated to reflect the changed method signature.

3) Support validating a token per realm
 
In CXF 2.5.0 the current realm is ignored when validating a token. In CXF 2.5.1, support has been added to include the current realm when querying a TokenValidator implementation to see if it can "handle" a given token. In addition, all TokenValidator implementations that ship with the STS return a Principal as part of the TokenValidatorResponse object, regardless of whether validation was successful or not.

4) OnBehalfOf Token Validation
 
In CXF 2.5.0 the responsibility for validating "OnBehalfOf" tokens was delegated to the TokenProvider implementation. In CXF 2.5.1, OnBehalfOf Token Validation has been moved to the TokenIssueOperation, and so OnBehalfOf Tokens are validated for all subsequent TokenProviders. This validation is achieved by querying a list of TokenValidator implementations to see if any can validate the received token. If validation is successful, then the state of the ReceivedToken (VALID, INVALID, NONE) is updated to reflect this. If no TokenValidator implementation exists that can validate the OnBehalfOf token, then the token has a state set to INVALID. Identity Mapping also now applies to the (VALID) OnBehalfOf Token.

5) Support for OnBehalfOf in the SAMLTokenProvider
 
In CXF 2.5.0, the SAMLTokenProvider can issue a SAML token based on the authenticated principal associated with the request, e.g. the principal associated with the security token in the WS-Security header. It does not support the scenario that a client is requesting a SAML token "OnBehalfOf" another SAML Token, in other words that the principal name associated with the "OnBehalfOf" token is used as the subject name of the issued SAML token. This functionality has been added in CXF 2.5.1.

6) Validate SAML Conditions against the current time

Support has been added to validate the Conditions of a received SAML Token against the current time.
Categories: Colm O hEigeartaigh

WS-SecurityPolicy Examples in Apache CXF

Colm O hEigeartaigh - Tue, 12/20/2011 - 13:35
The OASIS WS-SecurityPolicy Examples Version 1.0 specification gives a set of example policies for standard security deployments, as well as the corresponding message exchanges generated by those policies. The policies in the spec cover UsernameTokens, X509 Tokens, SAML Tokens and SecureConversation, used in conjunction with various security bindings (symmetric/asymmetric/transport).

I have implemented a set of system tests in Apache CXF that use these policies with a standard "double it" web service invocation. All of the policies in the specification are covered, apart from 2.2.2.1 which is an uncommon use-case of using an IssuedToken policy to reference an agreed out-of-band token.

The example tests are a good way of understanding how to implement and use various security policies. Here are links to the various tests and WSDLs which include the corresponding security policies:
Categories: Colm O hEigeartaigh

Apache Santuario (XML Security for Java) 1.5.0 RC1

Colm O hEigeartaigh - Mon, 12/19/2011 - 17:16
A release candidate for Apache Santuario (XML Security for Java) 1.5.0 has been published. Please download it and post any issues that are found to the mailing list. The 1.5.0 release is not binary compatible with the 1.4.x code due to extensive refactoring. Some of the more significant changes are as follows:

1) JDK 1.4.x support dropped

The 1.5.0 release drops support for JDK 1.4.x (see here and here). The APIs have been updated to use generics where possible.

2) Xalan is no longer a required dependency

Xalan/Xerces/Xml-apis are now optional dependencies, and have been marked as such in the pom. These libraries are only required if you want to support the XPath here() function, which is not supported by the XPath API in the JDK.

3) GCM support added

Support for GCM algorithms has been added via a third-party provider. See here for an example of how this is done in Apache WSS4J via BouncyCastle.

4) JSR-105 provider has been renamed

The Santuario JSR-105 provider "org.jcp.xml.dsig.internal.XMLDSigRI" has been renamed as "org.apache.jcp.xml.dsig.internal.XMLDSigRI". This is to avoid conflict with the JDK provider of the same name. In addition, the XMLDSigRI provider's name has changed from "XMLDSig" to "ApacheXMLDSig". See here for more details.

Please note that it won't be possible to drop in the xmlsec.jar inthe endorsed directory anymore and expect it to override the JDK's JSR 105provider. You will need to edit the java.security file to register the newprovider, or hard-code the provider name in your application code.

5) Secure Validation property

A new property has been added to enable "secure validation". This property is false by default. When set to true, it enforces the following processing rules:
  • Limits the number of Transforms per Reference to a maximum of 5.
  • Does not allow XSLT transforms. 
  • Does not allow a RetrievalMethod to reference another RetrievalMethod. 
  • Does not allow a Reference to call the ResolverLocalFilesystem orthe ResolverDirectHTTP (references to local files and HTTP resourcesare forbidden). 
  • Limits the number of references per Manifest (SignedInfo) to a maximum of 30. 
  • MD5 is not allowed as a SignatureAlgorithm or DigestAlgorithm. 
This functionality is supported in the core library through additional method signatures which take a boolean, and in the JSR-105 API via the property "org.apache.jcp.xml.dsig.secureValidation, e.g.:

XMLValidateContext context = new DOMValidateContext(key, elem);
context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE); 

6) Dynamic registration of default algorithms

The 1.4.x release loads all supported algorithms/implementations by reading and parsing an xml configuration file. This gives the user the power to override the default configuration file by setting the appropriate system property, and to add/remove algorithms as desired.

The downside to the current configuration approach is the performance issue of reading a file from the filesystem, parsing it, and then class-loading all of the implementations. Given that the majority of users probably just use the default algorithms that come with the library, this represents a performance issue on start-up.

In 1.5.0, the default algorithms are loaded dynamically. To revert to the older behaviour of loading algorithms from a properties file then set the System property "org.apache.xml.security.resource.config" to point to the file. 

7) The IdResolver no longer searches for Elements in "known" namespaces

The IdResolver class is responsible for retrieving Elements for a given Id. In the 1.5.0 release it will no longer attempt to search the current Document for an Element matching the requested Id in certain "known" namespaces (e.g. SOAP Message Security). It is the responsibility of the user to register Elements by Id in the IdResolver, if they are required as part of the signature validation process. This can be done via the "setIdAttributeNS" method in the DOMCryptoContext for users of the JSR-105 API.

Categories: Colm O hEigeartaigh

Apache CXF STS documentation - part XII

Colm O hEigeartaigh - Tue, 11/22/2011 - 17:57

A previous blog post detailed the AbstractOperation class that provides some core functionality for the STS operations, such as parsing the client request into a format that the TokenProviders/TokenValidators/TokenCancellers can consume. In this, the final post of this series of articles on the Apache CXF STS, we will examine an extension of AbstractOperation that is used to cancel tokens. Finally, we will look at the STS sample that ships with the CXF 2.5.x distribution.

1) The TokenCancelOperation

TokenCancelOperation is used to cancel tokens in the STS. It implements the CancelOperation interface in the STS provider framework. In addition to the properties that it inherits from AbstractOperation (detailed previously), it has a single property that can be configured:

  • List<TokenCanceller> tokencancellers - A list of TokenCanceller implementations to use to cancel tokens.

Recall that AbstractOperation uses the RequestParser to parse a client request into TokenRequirements and KeyRequirementsobjects. TokenCancelOperation first checks that a "CancelTarget" token was received and successfully parsed (if so it will be stored in the TokenRequirements object). If no token was received then an exception is thrown.

TokenCancelOperation then populates a TokenCancellerParametersobject with values extracted from the TokenRequirements and KeyRequirements objects. It iterates through the list of defined TokenCanceller implementations to see if any "can handle" the received token. If no TokenCanceller is defined, or if no TokenCanceller can handle the received token, then an exception is thrown. Otherwise, the received token is cancelled. If there is an error in cancelling the token, then an exception is also thrown. A response is constructed with the context attribute (if applicable), and the cancelled token type.

2) The STS sample in Apache CXF

Finally, we'll take a brief look at the STS sample that ships with Apache CXF. Download and extract the Apache CXF 2.5.x distribution. Navigate into "samples/sts" and take a look at the README.txt. The service provider has a policy that requires a SAML 2.0 token issued by an STS. The client authenticates itself to the STS with a UsernameToken over the symmetric binding. The STS issues a SAML 2.0 token to the client, which sends it to the service. The IssuedToken is defined as an InitiatorToken of an Asymmetric binding in the policy of the service, and so the client will use the secret key associated with the Subject of the Assertion to sign various parts of the message.

Build the sample with "mvn install", and then open up three separate command prompts. Start the STS with "mvn -Psts" in one, and start the service with "mvn -Pserver" in another. Finally, start the sample in the other window with "mvn -Pclient". You will see the (encrypted) messages flowing first between the client and the STS, and then between the client and the service provider.

Categories: Colm O hEigeartaigh

Apache CXF STS documentation - part XI

Colm O hEigeartaigh - Mon, 11/21/2011 - 15:14

A previous blog post detailed the AbstractOperation class that provides some core functionality for the STS operations, such as parsing the client request into a format that the TokenProviders/TokenValidators/TokenCancellers can consume. In this post we will examine an extension of AbstractOperation that is used to validate tokens.

1) The TokenValidateOperation

TokenValidateOperation is used to validate tokens in the STS. It implements the ValidateOperation interface in the STS provider framework. In addition to the properties that it inherits from AbstractOperation (detailed previously), it has a single property that can be configured:

  • List<TokenValidator> tokenValidators - A list of TokenValidator implementations to use to validate tokens.

Recall that AbstractOperation uses the RequestParser to parse a client request into TokenRequirements and KeyRequirements objects. TokenValidateOperation first checks that a "ValidateTarget" token was received and successfully parsed (if so it will be stored in the TokenRequirements object). If no token was received then an exception is thrown.

2) Token validation and response

TokenValidateOperation then populates a TokenValidatorParameters object with values extracted from the TokenRequirements and KeyRequirements objects. It iterates through the list of defined TokenValidator implementations to see if any "can handle" the received token. If no TokenValidator is defined, or if no TokenValidator can handle the received token, then an exception is thrown. Otherwise, the received token is validated. The TokenValidateOperation then checks to see whether token transformation is required.

2.1) Token Transformation

If the received token is successfully validated, and if the client supplies a TokenType in the request that does not correspond to the WS-Trust "status" namespace, then the TokenValidateOperation attempts to transform the validated token into a token of the requested type. Token transformation works in a similar way to token issuing, as detailed previously. A TokenProviderParameters object is constructed and the same processing steps (Realm parsing, AppliesTo parsing) are followed as for token issuing.

One additional processing step occurs before the token is transformed. If the TokenValidatorResponse object has a principal that was set by the TokenValidator implementation, then it is set as the principal of the TokenProviderParameters object. However, it is possible that the token is being issued in a different realm to that of the validated token, and the principal might also need to be transformed. Recall that the STSPropertiesMBean configuration object defined on AbstractOperation has an IdentityMapper property. This interface is used to map identities across realms. It has a single method:

  • Principal mapPrincipal(String sourceRealm, Principal sourcePrincipal, String targetRealm) - Map a principal from a source realm to a target realm

If the source realm is not null (the realm of the validated token as returned in TokenValidatorResponse), and if it does not equal the target realm (as set by the RealmParser), then the identity mapper is used to map the principal to the target realm and this is stored in TokenProviderParameters for use in token generation. After the (optional) identity mapping step, TokenValidateOperation iterates through the TokenProvider list to find an implementation that can "handle" the desired token type in the given (target) realm (if applicable). If no TokenProvider is defined, or if no TokenProvider can handle the desired token type, then an exception is thrown.

2.2) Token response

After token validation has been performed, and after any optional token transformation steps, a response object is constructed containing the following items:

  • The context attribute (if any was specified).
  • The received Token Type (if any was specified, or the "status" token type if validation was successful).
  • Whether the received token was valid or not (status code & reason).
  • If the received token was valid, and if token transformation successfully occurred:
    • The transformed token.
    • The lifetime of the transformed token.
    • A number of references to that token (can be disabled by configuration).
3) TokenValidateOperation example

Finally, it's time to look at an example of how to spring-load the STS so that it can validate tokens. This particular example uses a security policy that requires a UsernameToken over the transport binding (client auth is disabled). As the STS is a web service, we first define an endpoint:

<jaxws:endpoint id="transportSTS"
implementor="#transportSTSProviderBean"
address="http://.../SecurityTokenService/Transport"
wsdlLocation=".../ws-trust-1.4-service.wsdl"
xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
serviceName="ns1:SecurityTokenService"
endpointName="ns1:Transport_Port">
<jaxws:properties>
<entry key="ws-security.callback-handler" value="..."/>
</jaxws:properties>
</jaxws:endpoint>

The CallbackHandler JAX-WS property is used to validate the UsernameToken. The "implementor" of the jaxws:endpoint is the SecurityTokenServiceProvider class defined in the STS provider framework:

<bean id="transportSTSProviderBean"
class="org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider">
...
<property name="validateOperation" ref="transportValidateDelegate"/>
</bean>

This bean supports the Validate Operation via a TokenValidateOperation instance:

<bean id="transportValidateDelegate"
class="org.apache.cxf.sts.operation.TokenValidateOperation">
<property name="tokenValidators" ref="transportTokenValidators"/>
<property name="stsProperties" ref="transportSTSProperties"/>
</bean>

This TokenValidateOperation instance has a number of different TokenValidator instances configured:

<util:list id="transportTokenValidators">
<ref bean="transportSamlTokenValidator"/>
<ref bean="transportX509TokenValidator"/>
<ref bean="transportUsernameTokenValidator"/>
</util:list>

<bean id="transportX509TokenValidator"
class="org.apache.cxf.sts.token.validator.X509TokenValidator"/>

<bean id="transportUsernameTokenValidator"
class="org.apache.cxf.sts.token.validator.UsernameTokenValidator"/>

<bean id="transportSamlTokenValidator"
class="org.apache.cxf.sts.token.validator.SAMLTokenValidator"/>
</bean>

Finally the STSPropertiesMBean object that is used is given as follows:

<bean id="transportSTSProperties"
class="org.apache.cxf.sts.StaticSTSProperties">
<property name="signaturePropertiesFile" value="..."/>
<property name="signatureUsername" value="mystskey"/>
<property name="callbackHandlerClass" value="..."/>
<property name="encryptionPropertiesFile" value="..."/>
<property name="issuer" value="DoubleItSTSIssuer"/>
<property name="encryptionUsername" value="myservicekey"/>
</bean>
Categories: Colm O hEigeartaigh

Apache CXF STS documentation - part X

Colm O hEigeartaigh - Tue, 11/15/2011 - 15:56

The previous blog post introduced the TokenIssueOperation, which is used to issue tokens in the STS. The article covered the various processing steps that the TokenIssueOperation does on the parsed request, before it calls a TokenProvider instance to provide a token that is returned to the client. One step that was not covered was claims handling, as this is a complex topic that merits a deeper discussion. In this post, we will look at how claims are handled in the STS as a whole.

1) Claims Handling in the STS

A typical scenario for WS-Trust is when the client requires a particular security token from an STS to access a service provider. The service provider can let the client know what the requirements are for the security token in an IssuedToken policy embedded in the WSDL of the service. In particular, the service provider can advertise the claims that the security token must contain in the policy (either directly as a child element of IssuedToken, or else as part of the RequestSecurityTokenTemplate). An example is contained in the STS systests:


<sp:RequestSecurityTokenTemplate>
<t:TokenType>http://...#SAMLV1.1</t:TokenType>
<t:KeyType>http://.../PublicKey</t:KeyType>
<t:Claims Dialect="http://.../identity">
<ic:ClaimType Uri="http://.../claims/role"/>
</t:Claims>
</sp:RequestSecurityTokenTemplate>

This template specifies that a SAML 1.1 Assertion is required with an embedded X509 Certificate in the subject of the Assertion. The issued Assertion must also contain a "role" claim. The template is sent verbatim by the client to the STS when requesting a security token.

1.1) Parsing claims

The RequestParser object parses the client request into TokenRequirements and KeyRequirements objects. As part of this processing it converts a received Claims element into a RequestClaimCollection object. The RequestClaimCollection is just a list of RequestClaim objects, along with a dialect URI. The RequestClaim object holds the claimType URI as well as a boolean indicating whether the claim is optional or not.

1.2) The ClaimsHandler

The ClaimsHandler is an interface that the user must implement to be able to "handle" a requested claim. It has two methods:

  • List getSupportedClaimTypes() - Return the list of ClaimType URIs that this ClaimHandler object can handle.
  • ClaimCollection retrieveClaimValues(Principal principal, RequestClaimCollection claims) - Return the claim values associated with the requested claims (and client principal).

The ClaimCollection object that is returned is just a list of Claim objects. This object represents a Claim that has been processed by a ClaimsHandler instance. It essentially contains a number of properties that the ClaimsHandler implementation will set, e.g.:

  • URI claimType - The claimtype URI as received from the client.
  • String value - The claim value

Each Claim object in a ClaimCollection corresponds to a RequestClaim object in the RequestClaimCollection, and contains the Claim value corresponding to the requested claim. How the ClaimsHandler is invoked to create the ClaimCollection will be covered later. The STS ships with a single ClaimsHandler implementation, the LDAPClaimsHandler, which can retrieve claims from an LDAP store. A simpler example is available in the unit tests.

1.3) The ClaimsManager

Recall that in the previous post, the TokenIssueOperation has a single additional property that can be configured:

  • ClaimsManager claimsManager - An object that is used to handle claims.

The ClaimsManager holds a list of ClaimsHandler objects. So to support claim handling in the STS, it is necessary to implement one or more ClaimsHandler objects for whatever Claim URIs you wish to support, and register them with a ClaimsManager instance, which will be configured on the TokenIssueOperation object.

As detailed in the previous article, the TokenIssueOperation gets the realm of the current request, and does some processing of the AppliesTo address, after the RequestParser has finished parsing the request. The RequestClaimCollection object that has been constructed by the RequestParser is then processed. For each RequestClaim in the collection, it checks to see whether the ClaimsManager has a ClaimsHandler implementation registered that can "handle" that Claim (by checking the URIs). If it does not, and if the requested claim is not optional, then an exception is thrown.

If a ClaimsHandler implementation is registered with the ClaimsManager that can handle the desired claim, then the claims are passed through to the TokenProvider implementation, which is expected to be able to invoke the relevant ClaimHandler object, and insert the processed Claim into the generated security token. How this is done is entirely up to the user. For example, for the use-case given above of a SAML 1.1 token containing a "role" claim, the user could implement a custom AttributeStatementProvider instance that evaluates the claim values (via a custom ClaimsHandler implementation registered with the ClaimsManager) and constructs a set of Attributes accordingly in an AttributeStatement. An example of how to do this is given in the unit tests.

Categories: Colm O hEigeartaigh

Pages

Subscribe to Talend Community Coders aggregator - Colm O hEigeartaigh