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

Apache CXF STS documentation - part IX

Colm O hEigeartaigh - Thu, 11/10/2011 - 15:35

The 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 issue tokens.

1) The TokenIssueOperation

TokenIssueOperation is used to issue tokens in the STS. It implements the IssueOperation and IssueSingleOperation interfaces in the STS provider framework. In addition to the properties that it inherits from AbstractOperation (detailed in the previous post), it has a single property that can be configured:

  • ClaimsManager claimsManager - An object that is used to handle claims. This will be covered in a future post.

Recall that AbstractOperation uses the RequestParser to parse a client request into TokenRequirements and KeyRequirements objects. TokenIssueOperation populates a TokenProviderParameters object with values extracted from the TokenRequirements and KeyRequirements objects. A number of different processing steps then occur before a TokenProvider implementation is used to retrieve the desired token, comprising of realm parsing, claims handling, and AppliesTo parsing.Claims handling will be discussed in the next article.

1.1) Realm Parsing

We have discussed how realms are used with TokenProviders to provide tokens, and also how they work with TokenValidators to validate a given token. However, we did not cover how realms are defined in the first place. Recall that the STSPropertiesMBean configuration object defined on AbstractOperation has a RealmParser property. The RealmParser is an interface which defines a pluggable way of defining a realm for the current request. It has a single method:

  • String parseRealm(WebServiceContext context) - Return the realm of the current request given a WebServiceContext object.

Therefore if you wish to issue tokens in multiple realms, it is necessary to create an implementation of the RequestParser which will return a realm String given a context object. For example, different realms could be returned based on the endpoint URL or a HTTP parameter. This realm will then get used to select a TokenProvider implementation to use to issue a token of the desired type. It will also be used for token validation in a similar way.

1.2) AppliesTo parsing

An AppliesTo element contains an address that refers to the recipient of the issued token. If an AppliesTo element was sent as part of the request then the CXF STS requires that it must be explicitly handled. This is done by the list of ServiceMBean objects that can be configured on AbstractOperation. The ServiceMBean interface represents a service, and has the following methods (amongst others):

  • boolean isAddressInEndpoints(String address) - Return true if the supplied address corresponds to a known address for this service.
  • void setEndpoints(List<String> endpoints) - Set the list of endpoint addresses that correspond to this service.

The STS ships with a single implementation of this interface, the StaticService. For the normal use-case of handling an AppliesTo element, the user creates a StaticService object and calls setEndpoints with a set of Strings that correspond to a list of regular expressions that match the allowable set of token recipients (by address). The TokenIssueOperation will extract the URL address from the EndpointReference child of the received AppliesTo element, and then iterate through the list of ServiceMBean objects and ask each one whether the given address is known to that ServiceMBean object. If an AppliesTo address is received, and no ServiceMBean is configured that can deal with that URL, then an exception is thrown.

The ServiceMBean also defines a number of optional configuration options, such as the default KeyType and TokenType Strings to use for that Service, if the client does not supply them. It also allows the user to set a custom EncryptionProperties object, which defines a set of acceptable encryption algorithms to use to encrypt issued tokens for that service.

2) Token creation and response

Once the TokenIssuerOperation has processed the client request, it iterates through the list of defined TokenProvider implementations to see if each "can handle" the desired token type in the configured realm (if any). If no TokenProvider is defined, or if no TokenProvider can handle the desired token type, then an exception is thrown. Otherwise, a token is created, and a response object is constructed containing the following items:

  • The context attribute (if any was specified).
  • The Token Type.
  • The requested token (possibly encrypted, depending on configuration).
  • A number of references to that token (can be disabled by configuration).
  • The received AppliesTo address (if any).
  • The RequestedProofToken (if a Computed Key Algorithm was used).
  • The Entropy generated by the STS (if any, can be encrypted).
  • The lifetime of the generated token.
  • The KeySize that was used (if any).

3) TokenIssueOperation Example

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


<jaxws:endpoint id="UTSTS"
implementor="#utSTSProviderBean"
address="http://.../SecurityTokenService/UT"
wsdlLocation=".../ws-trust-1.4-service.wsdl"
xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
serviceName="ns1:SecurityTokenService"
endpointName="ns1:UT_Port">
<jaxws:properties>
<entry key="ws-security.callback-handler" value="..."/>
<entry key="ws-security.signature.properties" value="stsKeystore.properties"/>
</jaxws:properties>
</jaxws:endpoint>

The jaxws:properties are required to parse the incoming message. The CallbackHandler is used to validate the UsernameToken and provide the password required to access the private key defined in the signature properties parameter. The "implementor" of the jaxws:endpoint is the SecurityTokenServiceProvider class defined in the STS provider framework:


<bean id="utSTSProviderBean"
class="org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider">
<property name="issueOperation" ref="utIssueDelegate"/>
...
</bean>

This bean supports the Issue Operation via a TokenIssueOperation instance:


<bean id="utIssueDelegate"
class="org.apache.cxf.sts.operation.TokenIssueOperation">
<property name="tokenProviders" ref="utSamlTokenProvider"/>
<property name="services" ref="utService"/>
<property name="stsProperties" ref="utSTSProperties"/>
</bean>

This TokenIssueOperation instance has a single TokenProvider configured to issue SAML Tokens (with a default Subject and Attribute statement):


<bean id="utSamlTokenProvider"
class="org.apache.cxf.sts.token.provider.SAMLTokenProvider">
</bean>

The TokenIssueOperation also refers to a single StaticService implementation, which in turn defines a single URL expression to use to compare any received AppliesTo addresses:


<bean id="utService"
class="org.apache.cxf.sts.service.StaticService">
<property name="endpoints" ref="utEndpoints"/>
</bean>

<util:list id="utEndpoints">
<value>http://localhost:(\d)*/(doubleit|metrowsp)/services/doubleit(UT|.*symmetric.*|.*)</value>
</util:list>

Finally, the TokenIssueOperation is configured with a StaticSTSProperties object. This class contains properties that define what private key to use to sign issued SAML tokens, as well as the Issuer name to use in the generated token.


<bean id="utSTSProperties"
class="org.apache.cxf.sts.StaticSTSProperties">
<property name="signaturePropertiesFile" value="stsKeystore.properties"/>
<property name="signatureUsername" value="mystskey"/>
<property name="callbackHandlerClass" value="..."/>
<property name="issuer" value="DoubleItSTSIssuer"/>
...
</bean>

Categories: Colm O hEigeartaigh

Apache CXF STS documentation - part VIII

Colm O hEigeartaigh - Tue, 11/08/2011 - 18:29
Previous blog posts on the Apache CXF STS have focused on how tokens are provided, validated and canceled in the STS. These operations are (at least in theory) relatively independent of WS-Trust. For example, they could be used as an API to provide/validate/etc tokens. In the next couple of posts we will look at the bigger picture of how this internal token handling functionality works in the context of a client invocation. In this post we will cover some common functionality that is used by all of the WS-Trust operations in the STS implementation.

1) AbstractOperation

In the first post of this series of articles, the STS provider framework in Apache CXF was introduced. A number of interfaces were defined for each of the operations that can be invoked on the STS. Before looking at the implementations of these interfaces that ship with the STS, we will look a base class that all of the operations extend, namely the AbstractOperation class. This class defines a number of properties that are shared with any subclasses, and can be accessed via set/get methods:
  • STSPropertiesMBean stsProperties - A configuration MBean that holds the configuration for the STS as a whole, such as information about the private key to use to sign issued tokens, etc.
  • boolean encryptIssuedToken - Whether to encrypt an issued token or not. The default is false.
  • List<ServiceMBean> services - A list of ServiceMBean objects, which correspond to "known" services. This will be covered later.
  • List<TokenProvider> - A list of TokenProvider implementations to use to issue tokens.
  • boolean returnReferences - Whether to return SecurityTokenReference elements to the client or not, that point to the issued token. The default is true.
  • STSTokenStore tokenStore - A cache used to store/retrieve tokens.
Several of the properties refer to issuing tokens - this is because this functionality is shared between the issuing and validating operations. At least one TokenProvider implementation must be configured, if the STS is to support issuing a token. Some of these properties have been seen in previous posts, for example the STSTokenStore cache was covered in a previous blog post. This cache could be shared across a number of different operations, or else kept separate. AbstractOperation also contains some common functionality to parse requests, encrypt tokens, create references to return to the client, etc.

1.1) STSPropertiesMBean

The AbstractOperation object must be configured with an STSPropertiesMBean object. This is an interface that encapsulates some configuration common to a number of different operations of the STS:
  • void configureProperties() - load and process the properties
  • void setCallbackHandler(CallbackHandler callbackHandler) - Set a CallbackHandler object. This is used in the TokenProviders/TokenValidators to retrieve passwords for various purposes.
  • void setSignatureCrypto(Crypto signatureCrypto) - Set a WSS4J Crypto object to use to sign tokens, or validate signed requests, etc.
  • void setSignatureUsername(String signatureUsername) - Set the default signature username to use (e.g. corresponding to a keystore alias)
  • void setEncryptionCrypto(Crypto encryptionCrypto) - Set a WSS4J Crypto object to use to encrypt issued tokens.
  • void setEncryptionUsername(String encryptionUsername) - Set the default encryption username to use (e.g. corresponding to a keystore alias)
  • void setIssuer(String issuer) - Set the default issuer name of the STS
  • void setSignatureProperties(SignatureProperties signatureProperties) - Set the SignatureProperties object corresponding to the STS.
  • void setRealmParser(RealmParser realmParser) - Set the object used to define what realm a request is in. This will be covered later.
  • void setIdentityMapper(IdentityMapper identityMapper) - Set the object used to map identities across realms. This will be covered later.
The STS ships with a single implementation of the STSPropertiesMBean interface - StaticSTSProperties. This class has two additional methods:
  • void setSignaturePropertiesFile(String signaturePropertiesFile)
  • void setEncryptionPropertiesFile(String encryptionPropertiesFile)
If no Crypto objects are supplied to StaticSTSProperties, then it will try to locate a properties file using these values, and create a WSS4J Crypto object internally from the properties that are parsed.

1.2) SignatureProperties

A SignatureProperties object can be defined on the STSPropertiesMBean. Note that this is unrelated to the signaturePropertiesFile property of StaticSTSProperties. This class provides some configuration relating to the signing of an issued token, as well as symmetric key generation. It has the following properties:
  • boolean useKeyValue - Whether to use a KeyValue or not to refer to a certificate in a signature. The default is false.
  • long keySize - The (default) key size to use when generating a symmetric key. The default is 256 bits.
  • long minimumKeySize - The minimum key size to use when generating a symmetric key. The requestor can specify a KeySize value to use. The default is 128 bits. 
  • long maximumKeySize - The maximum key size to use when generating a symmetric key. The requestor can specify a KeySize value to use. The default is 512 bits.
For example, when the client sends a "KeySize" element to the STS when requesting a SAML Token (and sending a SymmetricKey KeyType URI), the SAMLTokenProvider will check that the requested keysize falls in between the minimum and maximum key sizes defined above. If it does not, then the default key size is used.

2) Request Parsing

The first thing any of the AbstractOperation implementations do on receiving a request is to call some functionality in AbstractOperation to parse the request. This parsing is done by the RequestParser object, which iterates through the objects of the JAXB RequestSecurityTokenType. The request is parsed into two components, TokenRequirements and KeyRequirements, which are available on the RequestParser object and are subsequently passed to the desired TokenProvider/TokenValidator/etc objects.

2.1) TokenRequirements

The TokenRequirements class holds a set of properties that have been extracted and parsed by RequestParser. These properties loosely relate to the token itself, rather than anything to do with keys. The properties that can be set by RequestParser are:
  • String tokenType - The desired TokenType URI. This is required if a token is to be issued.
  • Element appliesTo - The AppliesTo element that was received in the request. This normally holds a URL that indicates who the recipient of the issued token will be.
  • String context - The context attribute of the request.
  • ReceivedToken validateTarget - This object holds the contents of a received "ValidateTarget" element, i.e. a token to validate.
  • ReceivedToken onBehalfOf - This object holds the contents of a received "OnBehalfOf" element.
  • ReceivedToken actAs - This object holds the contents of a received "ActAs" element.
  • ReceivedToken cancelTarget - This object holds the contents of a received "CancelTarget" element, i.e. a token to cancel.
  • Lifetime lifetime - The requested lifetime of the issued token. This just holds created and expires Strings, that are parsed from the request.
  • RequestClaimCollection claims - A collection of requested claims that are parsed from the request. This will be covered later.
The ReceivedToken class mentioned above parses a received token object, which can be a JAXBElement<?> or a DOM Element. If it is a JAXBElement then it must be either a UsernameToken, SecurityTokenReference, or BinarySecurityToken. If it is a reference to a security token in the security header of the request, then this token is retrieved and set as the ReceivedToken instead.

2.2) KeyRequirements

The KeyRequirements class holds a set of properties that have been extracted and parsed by RequestParser. These properties are anything to do with key handling or creation. The properties that can be set by RequestParser are:
  • String authenticationType - An optional authentication type URI. This is currently not used in the STS.
  • String keyType - The desired KeyType URI.
  • long keySize - The requested KeySize to use when generating symmetric keys.
  • String signatureAlgorithm - The requested signature algorithm to use when signing an issued token. This is currently not used in the STS.
  • String encryptionAlgorithm - The requested encryption algorithm to use when encrypting an issued token.
  • String c14nAlgorithm - The requested canonicalization algorithm to use when signing an issued token. This is currently not used in the STS.
  • String computedKeyAlgorithm - The computed key algorithm to use when creating a symmetric key.
  • String keywrapAlgorithm - The requested KeyWrap algorithm to use when encrypting a symmetric key.
  • X509Certificate certificate - A certificate that has been extracted from a "UseKey" element, for use in the SAML case when a PublicKey KeyType URI is specified.
  • Entropy entropy - This object holds entropy information extracted from the client request for use in generating a symmetric key. Only BinarySecret elements are currently supported. 
2.3) SecondaryParameters

RequestParser also supports parsing a "SecondaryParameters" element that might be in the request. This could be extracted from the WSDL of a service provider that specifies an IssuedToken policy by the client and sent to the STS as part of the RequestSecurityToken request. Only KeySize, TokenType, KeyType and Claims child elements are currently parsed.

Categories: Colm O hEigeartaigh

Apache CXF STS documentation - part VII

Colm O hEigeartaigh - Mon, 11/07/2011 - 18:00
Previous blog entries have covered TokenProviders and TokenValidators, used by the STS to provide and validate tokens respectively. The STS does not currently have any support for renewing tokens - although this may change in the future. The other STS operation on tokens that is of interest is the ability to cancel tokens that were issued by the STS. In this post I will detail an interface used to cancel tokens, as well as an implementation that ships with the STS.

1) The TokenCanceller interface

SecurityTokens are cancelled in the STS via the TokenCanceller interface. This interface is very similar to the TokenProvider and TokenValidator interfaces. It contains three methods:
  • void setVerifyProofOfPossession(boolean verifyProofOfPossession) - Whether to enable or disable proof-of-possession verification.
  • boolean canHandleToken(ReceivedToken cancelTarget) - Whether this TokenCanceller implementation can cancel the given token
  • TokenCancellerResponse cancelToken(TokenCancellerParameters tokenParameters) - Cancel a token using the given parameters
A client can cancel a security token via the STS by invoking the "cancel" operation. Assuming that the client request is authenticated and well-formed, the STS will iterate through a list of TokenCanceller implementations to see if they can "handle" the received token. If they can, then the implementation is used to cancel the received security token, and the cancellation result is returned to the client. The STS currently ships with a single TokenCanceller implementation, which can cancel SecurityContextTokens that were issued by the STS. Before we look at this implementation, let's look at the "cancelToken" operation in more detail. This method takes a TokenCancellerParameters instance, and returns a TokenCancellerResponse object.

2) TokenCancellerParameters and TokenCancellerResponse

The TokenCancellerParameters class is nothing more than a collection of configuration properties to use in cancelling the token, which are populated by the STS operations using information collated from the request, or static configuration, etc. The properties of the TokenCancellerParameters 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.
The "cancelToken" method returns an object of type TokenCancellerResponse. Similar to the TokenCancellerParameters object, this just holds a collection of objects that is parsed by the STS operation to construct a response to the client. It currently only has a single property:
  • boolean tokenCancelled - Whether the token was cancelled or not.
3) The SCTCanceller

The STS ships with a single implementation of the TokenCanceller interface, namely the SCTCanceller. The SCTCanceller is used to cancel a token known as a SecurityContextToken, that is defined in the WS-SecureConversation specification. The SCTProvider and the SCTValidator were covered previously. A SecurityContextToken essentially consists of a String Identifier which is associated with a particular secret key. The SCTCanceller can cancel a SecurityContextToken in either of the following namespaces:
  • http://schemas.xmlsoap.org/ws/2005/02/sc/sct
  • http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512
Recall that 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. The same applies for the SCTCanceller. A received SecurityContextToken is successfully cancelled only if it is stored in the cache and is removed from the cache without any errors. This generally implies that the STS must have previously issued the SecurityContextToken and stored it in the cache, unless the STS is sharing a distributed cache with other STS instances.

3.1) Enforcing proof-of-possession

Recall that the TokenCanceller interface has a method "setVerifyProofOfPossession" which defines whether proof-of-possession is required or not to cancel a security token. The default value for the SCTCanceller is "true". This means that for the client to successfully cancel a SecurityContextToken it must prove to the STS that it knows the secret key associated with that SecurityContextToken. The client must do this by signing some portion of the request with the same secret key that the SCTCanceller retrieves from the security token stored in the cache.
Categories: Colm O hEigeartaigh

Apache CXF STS documentation - part VI

Colm O hEigeartaigh - Fri, 11/04/2011 - 17:45
In the previous post, I covered the TokenValidator interface that is used by the CXF STS to validate tokens, and two implementations that ship with the STS to validate SecurityContextTokens and BinarySecurityTokens (X509 Certificates). In this post I will cover the other two TokenValidator implementations that ship with the STS, which can validate UsernameTokens and SAML Tokens (both 1.1 and 2.0).

1) The UsernameTokenValidator

The UsernameTokenValidator is used to validate WS-Security UsernameTokens. Two properties can be set directly on the UsernameTokenValidator:
  • void setValidator(Validator validator) - Set the WSS4J Validator instance to use to validate the received UsernameToken. The default is the UsernameTokenValidator (note that this is in WSS4J and not the same as the UsernameTokenValidator in the STS!).
  • void setUsernameTokenRealmCodec(UsernameTokenRealmCodec usernameTokenRealmCodec) - Set the UsernameTokenRealmCodec instance to use to return a realm from a validated token. This will be explained later.
The UsernameToken is first checked to make sure that it is well-formed. If it has no password element then it is rejected. If a cache is configured, then it sees if the UsernameToken has been previously stored in the cache (searching by wsu:Id). If it is, and if the retrieved SecurityToken has an "associated hash" corresponding to the hashcode of the received UsernameToken, then the received UsernameToken has already been validated, and no further validation is required. It is necessary to check the "associated hash" value, in case two different UsernameTokens are being compared that have the same wsu:Id. Note that the CXF STS does not have a UsernameTokenProvider as of yet, so for this use-case perhaps the cache is shared with a custom TokenProvider.

If the token is not stored in the cache, then the WSS4J Validator instance is used to validate the received UsernameToken. As stated above, the default implementation that is used is the UsernameTokenValidator in WSS4J. This implementation uses a CallbackHandler to supply a password to validate the UsernameToken. This CallbackHandler implementation is supplied by the STSPropertiesMBean object. WSS4J also ships with an implementation that validates a UsernameToken via a JAAS LoginModule, which can be plugged in to the STS UsernameTokenValidator. If validation is successful, then a principal is created from the received UsernameToken and set on the response.

2) Realms in the TokenValidators

Recall that the TokenValidator interface has a method that takes a realm parameter:
  • boolean canHandleToken(ReceivedToken validateTarget, String realm) - Whether this TokenValidator implementation can validate the given token in the given realm
How the STS knows what the desired realm is will be covered in a future post.  
Realms are handled in a slightly different way in TokenValidators compared to TokenProviders. Recall that for TokenProviders, the implementation is essentially asked whether it can provide a token in a given realm. For the SCTProvider, the realm is ignored in this method. However, when creating a token, the SCTProvider will store the given realm as a property associated with that token in the cache. The SAMLTokenProvider checks to see if the given realm is null, and if it is not null then the realmMap *must* contain a key which matches the given realm.

There is a subtle distinction between the realm passed to "canHandleToken" for TokenValidators and the realm returned after a token is validated as part of the TokenValidatorResponse object. The realm passed to "canHandleToken" is the realm to validate the token in. So for example, you could have two TokenValidator instances registered to validate the same token, but in different realms. All of the TokenValidator implementations that ship with the STS ignore the realm as part of this method. However, the method signature gives the user the option to validate tokens in different realms in a more flexible manner.

The realm that is returned as part of the TokenValidatorResponse is the realm that the validated token is in (if any). This can be different to the realm the token was validated in. The X509TokenValidator ignores this parameter altogether. The SCTValidator checks to see whether the SecurityToken that was stored in the cache has a realm property, and if so sets this on the TokenValidatorResonse. The UsernameTokenValidator and SAMLTokenValidator handle realms in a more sophisticated manner. I will cover the UsernameTokenValidator here, and the SAMLTokenValidator later. Recall that the UsernameTokenValidator has the following method:
  • void setUsernameTokenRealmCodec(UsernameTokenRealmCodec usernameTokenRealmCodec) - Set the UsernameTokenRealmCodec instance to use to return a realm from a validated token. 
The UsernameTokenRealmCodec has a single method:
  • String getRealmFromToken(UsernameToken usernameToken) - Get the realm associated with the UsernameToken parameter.
No UsernameTokenRealmCodec implementation is set by default on the UsernameTokenValidator, hence no realm is returned in TokenValidatorResponse. If an implemention is specified, then the UsernameTokenValidator will retrieve a realm from the UsernameTokenRealmCodec implementation corresponding to the validated UsernameToken. If a cache is configured, and the UsernameToken was already stored in the cache, then the realm is compared to the realm of the cached token, stored under the tag "org.apache.cxf.sts.token.realm". If they do not match then validation fails.

3) The SAMLTokenValidator

The SAMLTokenValidator is used to validate SAML (1.1 and 2.0) tokens. The following properties can be set directly on the SAMLTokenValidator:
  • void setValidator(Validator validator) - Set the WSS4J Validator instance to use to validate the received certificate. The default is SignatureTrustValidator.
  • void setSamlRealmCodec(SAMLRealmCodec samlRealmCodec) - Set the SAMLRealmCodec instance to use to return a realm from a validated token.
  • void setSubjectConstraints(List<String> subjectConstraints) - Set a list of Strings corresponding to regular expression constraints on the subject DN of a certificate that was used to sign an Assertion.
These methods are covered in more detail below. The Assertion is first checked to make sure that it is well-formed. If a cache is defined, then the signature value of the received assertion (if it is signed) is hashed and compared against the tokens in the cache (via getTokenByAssociatedHash()). If a match is found in the cache, then the Assertion is taken to be valid. If a match is not found, then the Assertion is validated.
    3.1) Validating a received SAML Assertion

    If the token is not stored in the cache then it must be validated. Firstly a check is performed to make sure that the Assertion is signed, if it is not then it is rejected. The signature of the Assertion is then validated using the Crypto object retrieved from the STSPropertiesMBean passed in the TokenValidatorParameters. Finally, trust is verified in the certificate/public-key used to sign the Assertion. This is done using the Validator object that can be configured via "setValidator". The default Validator is the WSS4J SignatureTrustValidator, which checks that the received certificate is known (or trusted) by the STS Crypto object.

    Recall that a List of Strings can be set on the SAMLTokenValidator via the "setSubjectConstraints" method. These Strings correspond to regular expression constraints on the subject DN of a certificate that was used to sign an Assertion. This provides additional flexibility to validate a received SAML Assertion. For example, the Assertion could be signed by an entity that has a certificate issued by a particular CA, which in turn is trusted by the STS Crypto object. However, one might want to restrict the list of "valid" entities who can sign a SAML Assertion. This can be done by adding a list of regular expressions that match the Subject DN of all acceptable certificates that might be used to sign a valid SAML Assertion. This matching is done by the CertConstraintsParser.

    3.2) Realm handling in the SAMLTokenValidator

    Recall that the SAMLTokenValidator has the following method:
    • void setSamlRealmCodec(SAMLRealmCodec samlRealmCodec) - Set the SAMLRealmCodec instance to use to return a realm from a validated token.
    The SAMLRealmCodec has a single method:
    • String getRealmFromToken(AssertionWrapper assertion) - Get the realm associated with the (SAML Assertion) parameter.
    No SAMLRealmCodec implementation is set by default on the SAMLTokenValidator, hence no realm is returned in TokenValidatorResponse. If an implemention is specified, then the SAMLTokenValidator will retrieve a realm from theSAMLRealmCodec  implementation corresponding to the validated Assertion. If a cache is configured, and the Assertion was already stored in the cache, then the realm is compared to the realm of the cached token, stored under the tag "org.apache.cxf.sts.token.realm". If they do not match then validation fails.

    Categories: Colm O hEigeartaigh

    Apache CXF STS documentation - part V

    Colm O hEigeartaigh - Wed, 11/02/2011 - 17:38
    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:
    • http://schemas.xmlsoap.org/ws/2005/02/sc/sct
    • http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512
    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:
    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.

    Categories: Colm O hEigeartaigh

    New Apache Santuario and CXF releases

    Colm O hEigeartaigh - Wed, 11/02/2011 - 17:15
    Apache Santuario 1.4.6 has been released - it is available for download here. This release fixes a thread safety issue with XML Signature, a bug fix for the Canonical XML 1.1 algorithm, as well as a number of other bug fixes. See the release notes for more information.

    Also, Apache CXF 2.5.0 has been released. This release features a brand new STS implementation - something I have been blogging extensively about. See Dan Kulp's blog for more thoughts on this release.
    Categories: Colm O hEigeartaigh

    Apache CXF STS documentation - part IV

    Colm O hEigeartaigh - Thu, 10/27/2011 - 13:45
    In the previous post I covered the TokenProvider interface, which is used to generate tokens in the STS, and an implementation that ships with the STS to generate SecurityContextTokens. In this post, I will cover the other TokenProvider implementation that ships with the STS, which issues SAML Tokens (both 1.1 and 2.0).

    1) The SAMLTokenProvider

    The SAMLTokenProvider can issue SAML 1.1 and SAML 2.0 tokens. To request a SAML 1.1 token, the client must use one of the following Token Types:
    • http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1
    • urn:oasis:names:tc:SAML:1.0:assertion
    To request a SAML 2.0 token, the client must use one of the following Token Types:
    • http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
    • urn:oasis:names:tc:SAML:2.0:assertion
    The following properties can be configured on the SAMLTokenProvider directly:
    • List<AttributeStatementProvider> attributeStatementProviders - A list of objects that can add attribute statements to the token.
    • List<AuthenticationStatementProvider> authenticationStatementProviders - A list of objects that can add authentication statements to the token.
    • List<AuthDecisionStatementProvider> authDecisionStatementProviders - A list of objects that can add authorization decision statements to the token.
    • SubjectProvider subjectProvider - An object used to add a Subject to the token.
    • ConditionsProvider conditionsProvider - An object used to add a Conditions statement to the token.
    • boolean signToken - Whether to sign the token or not. The default is true.
    • Map<String, SAMLRealm> realmMap - A map of realms to SAMLRealm objects.
    We will explain each of these properties in more detail in the next few sections.

    2) Realms in the TokenProviders

    As explained in the previous post, the TokenProvider interface has a method that takes a realm parameter:
    • boolean canHandleToken(String tokenType, String realm) - Whether this TokenProvider implementation can provide a token of the given type, in the given realm
    In other words, the TokenProvider implementation is being asked whether it can supply a token corresponding to the Token Type in a particular realm. How the STS knows what the desired realm is will be covered in a future post. However, we will explain how the realm is handled by the TokenProviders here. The SCTProvider ignores the realm in the canHandleToken method. In other words, the SCTProvider can issue a SecurityContextToken in *any* realm. If a realm is passed through via the TokenProviderParameters when creating the token, the SCTProvider will cache the token with the associated realm as a property (this was explained in the previous post).

    Unlike the SCTProvider, the SAMLTokenProvider does not ignore the realm parameter to the "canHandleToken" method. Recall that the SAMLTokenProvider has a property "Map<String, SAMLRealm> realmMap". The canHandleToken method checks to see if the given realm is null, and if it is not null then the realmMap *must* contain a key which matches the given realm. So if the STS implementation is designed to issue tokens in different realms, then the realmMap of the SAMLTokenProvider must contain the corresponding realms in the key-set of the map.

    The realmMap property maps realm Strings to SAMLRealm objects. The SAMLRealm class contains the following properties:
    • String issuer - the Issuer String to use in this realm
    • String signatureAlias - the keystore alias to use to retrieve the private key the SAMLTokenProvider uses to sign the generated token
    In other words, if the SAMLTokenProvider is "realm aware", then it can issue tokens with an issuer name and signing key specific to a given realm. If no realm is passed to the SAMLTokenProvider, then these properties are obtained from the "system wide" properties defined in the STSPropertiesMBean object passed as part of the TokenProviderParameters, which can be set via the following methods:
    • void setSignatureUsername(String signatureUsername)
    • void setIssuer(String issuer)
    Two additional properties are required when signing SAML Tokens. A password is required to access the private key in the keystore, which is supplied by a CallbackHandler instance. A WSS4J "Crypto" instance is also required which controls access to the keystore. These are both set on the STSPropertiesMBean object via:
    • void setCallbackHandler(CallbackHandler callbackHandler)
    • void setSignatureCrypto(Crypto signatureCrypto)
    Note that the signature of generated SAML Tokens can be disabled, by setting the "signToken" property of the SAMLTokenProvider to "false". As per the SCTProvider, the generated SAML tokens are stored in the cache with the associated realm stored as a property.

    3) Populating SAML Tokens

    In the previous section we covered how a generated SAML token is signed, how to configure the key used to sign the assertion, and how to set the Issuer of the Assertion. In this section we will describe how to populate the SAML Token itself. The SAMLTokenProvider is designed to be able to issue a wide range of SAML Tokens. It does this by re-using the SAML abstraction library that ships with Apache WSS4J, which defines a collection of beans that are configured and then assembled in a CallbackHandler to create a SAML assertion.

    3.1) Configure a Conditions statement

    The SAMLTokenProvider has a "ConditionsProvider conditionsProvider" property, which can be used to configure the generated Conditions statement which is added to the SAML Assertion. The ConditionsProvider has a method to return a ConditionsBean object, and a method to return a lifetime in seconds. The ConditionsBean holds properties such as the not-before and not-after dates, etc. The SAMLTokenProvider ships with a default ConditionsProvider implementation that is used to insert a Conditions statement in every SAML token that is generated. This implementation uses a default lifetime of 5 minutes, and set the Audience Restriction URI of the Conditions Statement to be the received "AppliesTo" address, which is obtained from the TokenProviderParameters object.

    The DefaultConditionsProvider can be configured to change the lifetime of the issued token. If you want to remove the ConditionsProvider altogether from the generation assertion, or implement a custom Conditions statement, then you must implement an instance of the ConditionsProvider interface, and set it on the SAMLTokenProvider.

    3.2) Configure a Subject

    The SAMLTokenProvider has a "SubjectProvider subjectProvider" property, which can be used to configure the Subject of the generated token, regardless of the version of the token. The SubjectProvider interface defines a single method to return a SubjectBean, given the token provider parameters, the parent Document of the assertion, and a secret key to use (if any). The SubjectBean contains the Subject name, name-qualifier, confirmation method, and KeyInfo element, amongst other properties. The SAMLTokenProvider ships with a default SubjectProvider implementation that is used to insert a Subject into every SAML Token that is generated.

    The DefaultSubjectProvider has a single configuration method to set the subject name qualifier. It creates a subject confirmation method by checking the received key type. The subject name is the name of the principal obtained from TokenProviderParameters. Finally, a KeyInfo element is set on the SubjectBean under the following conditions:
    • If a "SymmetricKey" Key Type algorithm is specified by the client, then the secret key passed through to the SubjectProvider is encrypted with the X509Certificate of the recipient, and added to the KeyInfo element. How the provider knows the public key of the recipient will be covered later.
    • If a "PublicKey" KeyType algorithm is specified by the client, the X509Certificate that is received as part of the "UseKey" request is inserted into the KeyInfo element of the Subject.
    If a "Bearer" KeyType algorithm is specified by the client, then no KeyInfo element is added to the Subject. For the "SymmetricKey" Key Type case, the SAMLTokenProvider creates a secret key using a SymmetricKeyHandler instance. The SymmetricKeyHandler first checks the key size that is supplied as part of the KeyRequirements object, by checking that it fits in between a minimum and maximum key size that can be configured. It also checks any client entropy that is supplied, as well as the computed key algorithm. It then creates some entropy and a secret key.

    To add a custom Subject element to an assertion, you must create your own SubjectProvider implementation, and set it on the SAMLTokenProvider.

    3.3) Adding Attribute Statements

    The SAMLTokenProvider has a "List<AttributeStatementProvider> attributeStatementProviders" property, which can be used to add AttributeStatments to the generated assertion. Each object in the list adds a single Attribute statement. The AttributeStatementProvider contains a single method to return an AttributeStatementBean given the TokenProviderParameters object. This contains a SubjectBean (for SAML 1.1 assertions), and a list of AttributeBeans. The AttributeBean object holds the attribute name/qualified-name/name-format, and a list of attribute values, amongst other properties.

    If no statement provider is configured in the SAMLTokenProvider, then the DefaultAttributeStatementProvider is invoked to create an Attribute statement to add to the assertion. It creates a default "authenticated" attribute, and also creates separate Attributes for any "OnBehalfOf" or "ActAs" elements that were received in the request. If the received OnBehalfOf/ActAs element was a UsernameToken, then the username is added as an Attribute. If the received element was a SAML Assertion, then the subject name is added as an Attribute. 

    3.4) Adding Authentication Statements

    The SAMLTokenProvider has a "List<AuthenticationStatementProvider> authenticationStatementProviders" property, which can be used to add AuthenticationStatements to the generated assertion. Each object in the list adds a single Authentication statement. The AuthenticationStatementProvider contains a single method to return an AuthenticationStatementBean given the TokenProviderParameters object. This contains a SubjectBean (for SAML 1.1 assertions), an authentication instant, authentication method, and other properties. No default implementation of the AuthenticationStatementProvider interface is provided in the STS, so if you want to issue Authentication Statements you will have to write your own.

    3.5) Adding Authorization Decision Statements

    The SAMLTokenProvider has a "List<AuthDecisionStatementProvider> authDecisionStatementProviders" property, which can be used to add AuthzDecisionStatements to the generated assertion. Each object in the list adds a single statement. The AuthDecisionStatementProvider  contains a single method to return an AuthDecisionStatementBean given the TokenProviderParameters object. This contains a SubjectBean (for SAML 1.1 assertions), the decision (permit/indeterminate/deny), the resource URI, a list of ActionBeans, amongst other properties. No default implementation of the AuthDecisionStatementProvider interface is provided in the STS.

    Note that for SAML 1.1 tokens, the Subject is embedded in one of the Statements. When creating a SAML 1.1 Assertion, if a given Authentication/Attribute/AuthzDecision statement does not have a subject, then the standalone Subject is inserted into the statement. Finally, once a SAML token has been created, it is stored in the cache (if one is configured), with a lifetime corresponding to that of the Conditions statement. A TokenProviderResponse object is created with the DOM representation of the SAML Token, the SAML Token ID, lifetime, entropy bytes, references, etc.
      Categories: Colm O hEigeartaigh

      Apache CXF STS documentation - part III

      Colm O hEigeartaigh - Tue, 10/25/2011 - 18:08
      In the next couple of blog posts I will describe how to generate tokens in the new STS implementation shipped as part of Apache CXF 2.5. In this post I will detail the interface that is used for generating tokens, as well as an implementation to generate SecurityContextTokens that ships with the STS. In the next post, I will describe how to generate SAML tokens.

      1) The TokenProvider interface

      Security tokens are created in the STS via the TokenProvider interface. It has three methods:
      • boolean canHandleToken(String tokenType) - Whether this TokenProvider implementation can provide a token of the given type
      • boolean canHandleToken(String tokenType, String realm) - Whether this TokenProvider implementation can provide a token of the given type, in the given realm
      • TokenProviderResponse createToken(TokenProviderParameters tokenParameters) - Create a token using the given parameters
      A client can request a security token from the STS by either invoking the "issue" operation and supplying a desired token type, or else calling the "validate" operation and passing a (different) token type (token transformation). Assuming that the client request is authenticated and well-formed, the STS will iterate through a list of TokenProvider implementations to see if they can "handle" the received token type. If they can, then the implementation is used to create a security token, which 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 issuing of a particular token type in an STS deployment, it is necessary to specify a TokenProvider implementation that can handle that token type. The STS currently ships with two TokenProvider implementations, one for generating SecurityContextTokens, and one for generating SAML Assertions. Before we look at these two implementations, let's take a look at the "createToken" operation in more detail. This method takes a TokenProviderParameters instance.

      2) TokenProviderParameters

      The TokenProviderParameters class is nothing more than a collection of configuration properties to use in creating the token, which are populated by the STS operations using information collated from the request, or static configuration, etc. The properties of the TokenProviderParameters are:
      • STSPropertiesMBean stsProperties - A configuration MBean that holds the configuration for the STS as a whole, such as information about the private key to use to sign issued tokens, etc. This will be covered later.
      • EncryptionProperties encryptionProperties - A properties object that holds encryption information relevant to the intended recipient of the token. This will be covered later.
      • Principal principal - The current client Principal object. This can be used as the "subject" of the generated token.
      • WebServiceContext webServiceContext - The current web service context object. This allows access to the client request.
      • RequestClaimCollection requestedClaims - The requested claims in the token. This will be covered later.
      • 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.
      • String appliesToAddress - The URL that corresponds to the intended recipient of the token
      • ClaimsManager claimsManager - An object that can manage claims. This will be covered later.
      • Map<String, Object> additionalProperties - Any additional (custom) properties that might be used by a TokenProvider implementation.
      • STSTokenStore tokenStore - A cache used to store tokens.
      • String realm - The realm to create 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 TokenProviderParameters object if you are creating your own TokenProvider implementation.

      3) TokenProviderResponse

      The "createToken" method returns an object of type TokenProviderResponse. Similar to the TokenProviderParameters 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:
      • Element token - The (DOM) token that was created by the TokenProvider.
      • String tokenId - The ID of the token
      • long lifetime - The lifetime of the token
      • byte[] entropy - Any entropy associated with the token
      • long keySize - The key size of a secret key associated with the token.
      • boolean computedKey - Whether a computed key algorithm was used in generating a secret key.
      • TokenReference attachedReference - An object which gives information how to refer to the token when it is "attached".
      • TokenReference unAttachedReference" - An object which gives information how to refer to the token when it is "unattached".
      Most of these properties are optional as far as the STS operation is concerned, apart from the token and token ID. The TokenReference object contains information about how to refer to the token (direct reference vs. Key Identifier, etc.), that is used by the STS to generate the appropriate reference to return to the client. 

      4) The SCTProvider

      Now that we've covered the TokenProvider interface, let's look at an implementation that is shipped with the STS. The SCTProvider is used to provide a token known as a SecurityContextToken, that is defined in the WS-SecureConversation specification. 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. How this is done is "out of band" (more on this later).

      To request a SecurityContextToken, the client must use one of the following Token Types:
      • http://schemas.xmlsoap.org/ws/2005/02/sc/sct
      • http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512
      Two properties can be configured on the SCTProvider directly:
      • long lifetime - The lifetime of the generated SCT. The default is 5 minutes.
      • boolean returnEntropy - Whether to return any entropy bytes to the client or not. The default is true.
      The SCTProvider generates a secret key using the KeyRequirements object that was supplied, and constructs a SecurityContextToken with a random Identifier. It creates a CXF SecurityToken object that wraps this information, and stores it in the supplied cache using the given lifetime. The SecurityContextToken element is then returned, along with the appropriate references, lifetime element, entropy, etc.

      When requesting a token from an STS, the client will typically present some entropy along with a computed key algorithm. The STS will generate some entropy of its own, and combine it with the client entropy using the computed key algorithm to generate the secret key. Alternatively, the client will present no entropy, and the STS will supply all of the entropy. Any entropy the STS generates is then returned to the client, who can recreate the secret key using its own entropy, the STS entropy, and the computed key algorithm.

      This secret key is then used for the SCT use-case to encrypt/sign some part of a message. The SecurityContextToken is placed in the security header of the message, and referred to in the KeyInfo element of the signed/encrypted structure. As noted earlier, the service provider must obtain somehow the secret key corresponding to the SecurityContextToken identifier. Perhaps the service provider shares a (secured) distributed cache with an STS instance. Or perhaps the service provider sends the SCT to an STS instance to "validate" it, and receives a SAML token in response with the embedded (encrypted) secret key.

      5) Token caching in the TokenProvider

      Finally, we will cover token caching in a TokenProvider implementation. The SCTProvider is essentially useless without a cache, as otherwise there is no way for a third-party to know the secret key corresponding to a SecurityContextToken. Any TokenProvider implementation can cache a generated token in the STSTokenStore object supplied as part of the TokenProviderParameters. This object simply wraps the TokenStore interface in the CXF WS-Security runtime, which itself contains basic methods for adding/removing/querying CXF SecurityToken objects.

      The SCTProvider creates a SecurityToken with the ID of the SCT, the secret key associated with the SCT and the client principal. If a "realm" is passed through, then this is recorded as a property of the SecurityToken (keyed via STSConstants.TOKEN_REALM). Finally, the STS ships with two STSTokenStore implementations, an in-memory implementation based on eh-cache, and an implementation that uses Hazelcast.

        Categories: Colm O hEigeartaigh

        Apache CXF STS documentation - part II

        Colm O hEigeartaigh - Fri, 10/21/2011 - 18:22
        In part I of the series of posts on the new Apache CXF STS implementation, I talked about what a Security Token Service can do, as well as the STS provider framework in CXF since the 2.4.0 release. In this part, I will leave the STS implementation to one side for the moment, and instead focus on how a client interacts with the STS in CXF.

        A simple example of how a CXF client can obtain a security token from the STS is shown in the "basic" STS system test "IssueUnitTest". This test starts an instance of the new CXF STS and obtains a number of different security tokens, all done completely programmatically, i.e. with no spring configuration. The STS instance that is used for the test-cases is configured with a number of different endpoints that use different security bindings (defined in the wsdl of the STS). For the purposes of this test, the Transport binding is used:

        <wsp:Policy wsu:Id="Transport_policy">
              <wsp:ExactlyOne>
                 <wsp:All>
                    <sp:TransportBinding
                       xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                       <wsp:Policy>
                          <sp:TransportToken>
                             <wsp:Policy>
                                <sp:HttpsToken RequireClientCertificate="false"/>
                             </wsp:Policy>
                          </sp:TransportToken>
                          <sp:AlgorithmSuite>
                             <wsp:Policy>
                                <sp:Basic128 />
                             </wsp:Policy>
                          </sp:AlgorithmSuite>
                          <sp:Layout>
                             <wsp:Policy>
                                <sp:Lax />
                             </wsp:Policy>
                          </sp:Layout>
                          <sp:IncludeTimestamp />
                       </wsp:Policy>
                    </sp:TransportBinding>
                    <sp:SignedSupportingTokens
                       xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                       <wsp:Policy>
                          <sp:UsernameToken
                             sp:IncludeToken=".../AlwaysToRecipient">
                             <wsp:Policy>
                                <sp:WssUsernameToken10 />
                             </wsp:Policy>
                          </sp:UsernameToken>
                       </wsp:Policy>
                    </sp:SignedSupportingTokens>
                    ...
                 </wsp:All>
              </wsp:ExactlyOne>
           </wsp:Policy>

        In other words, this security policy requires that a one-way TLS connection must be used to communicate with the STS, and that authentication is performed via a Username Token in the SOAP header.

        The object that communicates with an STS in CXF is the STSClient. Typically, the user constructs an STSClient instance (normally via Spring), sets it with certain properties such as the WSDL location of the STS, what service/port to use, various crypto properties, etc, and then stores this object on the message context using the SecurityConstants tag "ws-security.sts.client". This object is then controlled by the IssuedTokenInterceptorProvider in the ws-security runtime in CXF. This interceptor provider is triggered by the "IssuedToken" policy assertion, which is typically in the WSDL of the service provider. This policy assertion informs the client that it must obtain a particular security token from an STS and include it in the service request. The IssuedTokenInterceptorProvider takes care of using the STSClient to get a Security Token from the STS, and handles how long the security token should be cached, etc.

        An example of a simple IssuedToken policy that might appear in the WSDL of a service provider is as follows:

        <sp:IssuedToken sp:IncludeToken=".../AlwaysToRecipient">
            <sp:RequestSecurityTokenTemplate>
                <t:TokenType>
                    http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
                </t:TokenType>
                <t:KeyType>
                    http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer
                </t:KeyType>
            </sp:RequestSecurityTokenTemplate>
            ...
        </sp:IssuedToken>

        This policy states that the client should include a SAML 2.0 Assertion of subject confirmation method "Bearer" in the request. The client must know how to communicate with an STS to obtain such a token. This is done by providing the STSClient object with the appropriate information.

        We will come back to the IssuedTokenInterceptorProvider at a later date. The IssueUnitTest referred to above uses the STSClient programmatically to obtain a security token. Let's look at the "requestSecurityToken" method called by the tests. An STSClient is instantiated via the CXF bus, and the WSDL location of the STS, plus service and port names are configured:

        STSClient stsClient = new STSClient(bus);
        stsClient.setWsdlLocation("https://.../SecurityTokenService/Transport?wsdl");
        stsClient.setServiceName("{...}SecurityTokenService");
        stsClient.setEndpointName("{...}Transport_Port");

        A map is then populated with various properties and set on the STSClient. It is keyed with a different number of SecurityConstants tags. A username is supplied for use as the "user" in the UsernameToken. A CallbackHandler class is supplied to get the password to use in the UsernameToken. Compliance of the Basic Security Profile 1.1 is turned off, this is to prevent CXF throwing an exception when receiving a non-spec compliant response from a non-CXF STS:

        Map<String, Object> properties = new HashMap<String, Object>();
        stsClient.setProperties(properties);
        properties.put(SecurityConstants.USERNAME, "alice");
        properties.put(
                SecurityConstants.CALLBACK_HANDLER,
                "org.apache.cxf.systest.sts.common.CommonCallbackHandler"
        );
        properties.put(SecurityConstants.IS_BSP_COMPLIANT, "false");
              
        If the KeyType is a "PublicKey", then an X.509 Certificate is presented to the STS in the request to embed in the generated SAML Assertion. The X.509 Certificate is obtained from the keystore defined in "clientKeystore.properties", with the alias "myclientkey". Finally, the "useCertificateForConfirmationKeyInfo" property of the STSClient means that the entire certificate is to be included in the request, instead of a KeyValue (which is the default):

        if (PUBLIC_KEY_KEYTYPE.equals(keyType)) {
                properties.put(SecurityConstants.STS_TOKEN_USERNAME, "myclientkey");
                properties.put(SecurityConstants.STS_TOKEN_PROPERTIES, "clientKeystore.properties");
                stsClient.setUseCertificateForConfirmationKeyInfo(true);
        }

        Finally, the token type is set on the STSClient (the type of token that is being requested), as well as the KeyType (specific to a SAML Assertion), and a security token is requested, passing the endpoint address which is sent to the STS in the "AppliesTo" element:

                stsClient.setTokenType(tokenType);
                stsClient.setKeyType(keyType);
                return stsClient.requestSecurityToken(endpointAddress);

        The returned SecurityToken object contains the received token as a DOM element, the ID of the received token, any reference elements that were returned - which show how to reference the token, any secret associated with the token, and the lifetime of the token.
        Categories: Colm O hEigeartaigh

        Apache CXF STS documentation - part I

        Colm O hEigeartaigh - Wed, 10/19/2011 - 18:00
        The forthcoming Apache CXF 2.5 release will have an STS (Security Token Service) implementation which has been donated by Talend. This is the first in a series of blog posts where I will be going into the STS implementation in detail. In this post I will be explaining what an STS is and talking about the STS provider framework in CXF.

        1) What is a Security Token Service?

        An informal description of a Security Token Service is that it is a web service that offers some or all of the following services (amongst others):
        • It can issue a Security Token of some sort based on presented or configured credentials.
        • It can say whether a given Security Token is valid or not
        • It can renew (extend the validity of) a given Security Token
        • It can cancel (remove the validity of) a given Security Token
        • It can transform a given Security Token into a Security Token of a different sort.
        Offloading this functionality to another service greatly simplifies client and service provider functionality, as they can simply call the STS appropriately rather than have to figure out the security requirements themselves. For example, the WSDL of a service provider might state that a particular type of security token is required to access the service. A client of the service can ask an STS for a Security Token of that particular type, which is then sent to the service provider. The service provider could choose to validate the received token locally, or dispatch the token to an STS for validation. These are the two most common use-cases of an STS.

        A client can communicate with the STS via a protocol defined in the WS-Trust specification. The SOAP Body of the request contains a "RequestSecurityToken" element that looks like:

        <wst:RequestSecurityToken Context="..." xmlns:wst="...">
            <wst:TokenType>...</wst:TokenType>
            <wst:RequestType>...</wst:RequestType>
            <wst:SecondaryParameters>...</wst:SecondaryParameters>
            ...
        </wst:RequestSecurityToken>

        The Apache CXF STS implementation supports a wide range of parameters that are passed in the RequestSecurityToken element. The SOAP Body of the response from the STS will contain a "RequestSecurityTokenResponse(Collection)" element, e.g.:

        <wst:RequestSecurityTokenResponseCollection xmlns:wst="...">
            <wst:RequestSecurityTokenResponse>
            ...
            </wst:RequestSecurityTokenResponse>
        </wst:RequestSecurityTokenResponseCollection>

        1.1 A sample request/response for issuing a Security Token

        A sample client request is given here, where the client wants the STS to issue a SAML 2.0 token for the "http://cxf.apache.org:8080/service" service:

        <wst:RequestSecurityToken Context="..." xmlns:wst="...">
            <wst:TokenType>
               http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
            </wst:TokenType>
            <wst:RequestType>
                http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue
            </wst:RequestType>
            <wsp:AppliesTo>http://cxf.apache.org:8080/service</wsp:AppliesTo>
        </wst:RequestSecurityToken>

        The STS responds with:

        <wst:RequestSecurityTokenResponseCollection xmlns:wst="...">
            <wst:RequestSecurityTokenResponse>
                 <wst:TokenType>
                 http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
                 </wst:TokenType>
                 <wst:RequestedSecurityToken>
                     <saml2:Assertion xmlns:saml2="..." ... />
                 </wst:RequestedSecurityToken>
            </wst:RequestSecurityTokenResponse>
        </wst:RequestSecurityTokenResponseCollection>

        2) The STS provider framework in Apache CXF

        The first support for an STS in Apache CXF appeared in the 2.4.0 release with the addition of an STS provider framework in the WS-Security module. This is essentially an API that can be used to create your own STS implementation. As the STS implementation shipped in CXF 2.5 is based on this provider framework, it makes sense to examine it in more detail.

        The SEI (Service Endpoint Interface) is available here. It contains the following methods that are relevant to the STS features discussed above:
        • RequestSecurityTokenResponseCollectionType issue(RequestSecurityTokenType request) - to issue a security token
        • RequestSecurityTokenResponseType issueSingle( RequestSecurityTokenType request) - to issue a security token that is not contained in a "Collection" wrapper (for legacy applications).
        • RequestSecurityTokenResponseType cancel(RequestSecurityTokenType request) - to cancel a security token
        • RequestSecurityTokenResponseType validate(RequestSecurityTokenType request) - to validate a security token
        • RequestSecurityTokenResponseType renew(RequestSecurityTokenType request) - to renew a security token
        The SEI implementation handles each request by delegating it to a particular operation, which is just an interface that must be implemented by the provider framework implementation. Finally, a JAX-WS provider is available, which dispatches a request to the appropriate operation.

        Significant updates to the STS Provider framework after the CXF 2.4.0 release include support for SOAP 1.2, a major bug fix to support operations other than issue,  better exception propagation, and adding support for the WS-Trust 1.4 schema. These features are all available in the Apache CXF 2.4.3 release onwards.
        Categories: Colm O hEigeartaigh

        Pages

        Subscribe to Talend Community Coders aggregator - Colm O hEigeartaigh