Thursday, August 27, 2015

Apache CXF Fediz 1.2.1 and 1.1.3 released

Apache CXF Fediz 1.2.1 and 1.1.3 have been released. Both releases contain updates to the underlying CXF dependency, as well as a number of minor bug-fixes and improvements. However the most important enhancement is a fix for a recent security advisory:
  • CVE-2015-5175: Apache CXF Fediz application plugins are vulnerable to Denial of Service (DoS) attacks
Apache CXF Fediz is a subproject of Apache CXF which implements the WS-Federation Passive Requestor Profile for SSO specification. It provides a number of container based plugins to enable SSO for Relying Party applications. These plugins are potentially vulnerable to DoS attacks due to the fact that support for Document Type Declarations (DTDs) is not disabled when parsing the response from the Identity Provider (IdP).

Tuesday, August 25, 2015

Apache CXF Fediz 1.2.0 tutorial - part VII

This is the seventh and final blog post on a series of new features introduced in Apache CXF Fediz 1.2.0. The previous post looked at the new REST API of the IdP. Up to now, we have only covered the basic scenario where the application and the IdP are in the same realm. However, a more sophisticated example is when the application is in a different realm. In this case, the IdP must redirect the user to the home IdP of the application for authentication. The IdP has supported this functionality up to now using WS-Federation only. However, the 1.2.0 IdP supports the ability to redirect to a SAML SSO IdP, thus acting as an identity broker between the two protocols. We will cover this functionality in this tutorial.

1) Setup simpleWebapp + SAML SSO IdP

As with previous tutorials, please follow the first tutorial to deploy the Fediz IdP + STS to Apache Tomcat, as well as the "simpleWebapp. However, this time the "simpleWebapp" is going to be deployed in a different realm. Edit 'conf/fediz_config.xml' and add the following under the "protocol" section:
  • <homeRealm type="String">urn:org:apache:cxf:fediz:idp:realm-B</homeRealm>
This tells the IdP that the application is to be authenticated in "realm-B".

The next thing we are going to do is to set up a SAML SSO IdP which will authenticate users who want to access "simpleWebapp". In this tutorial we will just use a mocked SAML SSO IdP in the Fediz system tests for convenience. Build the war as in the following steps + deploy to Tomcat:
2) Configure the Fediz IdP

Next we need to take a look at configuring the Fediz IdP so that it knows where to find the SAML SSO IdP associated with "realm B" and how to communicate with it. Edit 'webapps/fediz-idp/WEB-INF/classes/entities-realma.xml':

In the 'idp-realmA' bean:
  • Change the port in "idpUrl" to "8443". 
In the 'trusted-idp-realmB' bean:
  • Change the "url" value to "https://localhost:8443/samlssoidp/samlsso".
  • Change the "protocol" value to "urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser".
  • Add the following: <property name="parameters"><util:map><entry key="support.deflate.encoding" value="true" /></util:map></property>
The "parameters" map above is a way to provide SAML SSO specific configuration options to the Fediz IdP. The following options can be configured:
  • sign.request - Whether to sign the request or not. The default is "true".
  • require.keyinfo - Whether to require a KeyInfo or not when processing a (signed) Response. The default is "true".
  • require.signed.assertions - Whether the assertions contained in the Response must be signed or not. The default is "true".
  • require.known.issuer - Whether we have to "know" the issuer of the SAML Response or not. The default is "true".
  • support.base64.encoding - Whether we BASE-64 decode the response or not. The default is "true".
  • support.deflate.encoding - Whether we support Deflate encoding or not. The default is "false".
Redeploy the Fediz IdP + navigate to the following URL in a browser:
  • https://localhost:8443/fedizhelloworld/secure/fedservlet
You will see that the Fediz IdP will redirect the browser to the mocked SAML SSO IdP for authentication (authenticate with "ALICE/ECILA") and then back to the Fediz IdP and eventually back to the client application.

Wednesday, August 19, 2015

Apache CXF Fediz 1.2.0 tutorial - part VI

This is the sixth in a series of posts on the new features of Apache CXF Fediz 1.2.0. The previous post looked at Single Sign Out support in Fediz. In this article we will briefly cover the new REST API of the Fediz IdP. Prior to the 1.2.0 release all of the IdP configuration was done in a static way using Spring. If the IdP administrator wished to change the claims for a particular application, then the change would necessitate restarting the IdP. In contrast, the Fediz 1.2.0 IdP persists the configuration to a database using JPA. In addition, it allows access to this configuration via a REST API powered by Apache CXF.

To get started, please follow step 1 of the first tutorial to deploy the Fediz IdP to Apache Tomcat. The REST API is described by a WADL document available at the following URL:
  • https://localhost:8443/fediz-idp/services/rs?_wadl
The WADL document describes the following resource URIs:
  • services/rs/idps - An IdP for a given realm. 
  • services/rs/claims - The claims that are available in the IdP.
  • services/rs/applications - The applications that are defined in the IdP.
  • services/rs/trusted-idps - The trusted IdPs that are defined in the IdP.
  • services/rs/roles - The roles associated with the REST API.
By using the standard HTTP verbs in the usual way you can retrieve, store, modify and remove items from the IdP configuration. For example, to see (GET) the configuration associated with the IdP for "realm A" navigate to the following URL in a browser:
  • https://localhost:8443/fediz-idp/services/rs/idps/urn:org:apache:cxf:fediz:idp:realm-A
The user credentials are defined in "webapps/fediz-idp/WEB-INF/classes/". You can use "admin/password" by default to access the API. Here you can see the protocols supported, the token types offered, the different ways of authenticating to the IdP, the claim types offered, the applications supported, etc. Note that by default the information returned in a GET request is in XML format. You can return it in JSON format just by appending ".json" to the URL:
For much more information on how to use the new REST API, please see Oliver Wulff's blog on this topic.

Friday, August 7, 2015

Apache CXF Fediz 1.2.0 tutorial - part V

This is the fifth in a series of posts on the new features available in Apache CXF Fediz 1.2.0. The previous article described a new container-independent Relying Party (RP) plugin available in Fediz 1.2.0 based on Apache CXF. In this post we will take a look at two new features, support for Single Sign Out and the ability to publish metadata for both RP plugins and the IdP.

1) Single Sign Out support in Fediz

An important new feature in Fediz 1.2.0 is the ability to perform Single Sign Out both at the RP and IdP. The user can log out at either the RP or IdP by adding "?wa=wsignout1.0" to the relevant URL. Alternatively, two new configuration options are added for the RP:
  • logoutURL - The logout URL to trigger federated logout
  • logoutRedirectTo - URL landing-page after successful logout.
To see how this works in practice, follow the first tutorial to set up the hello world demo in Tomcat, and log on via:
  • https://localhost:8443/fedizhelloworld/secure/fedservlet
After successful authentication, you will see a basic webpage detailing the User principal, roles, and the underlying SAML Assertion. Now what if you want to log out from the application? From Fediz 1.2.0 it's simple. Navigate to the following URL:
  • https://localhost:8443/fedizhelloworld/secure/fedservlet?wa=wsignout1.0
The browser will be redirected to the logout page for the IdP:

Click "Logout" and you see a page confirming that Logout was successful (in both the RP + IdP). To confirm this, navigate again to the application URL, and you will see that you are redirected back to the IdP for authentication. The user can also logout directly at the IdP by navigating to:
  • https://localhost:8443/fediz-idp/federation?wa=wsignout1.0
2) Metadata Support in Fediz

It has been possible since Fediz 1.0.0 to publish the Metadata document associated with a Relying Party using the Tomcat plugin. This Metadata document is built dynamically using the Fediz configuration values and is published at the standard URL. Here is a screenshot of a request using the "fedizhelloworld" demo:

This document describes the endpoint address of the service, the realm of the service, and the claims (both required and optional). The metadata document can also be signed by specifying a "signingKey" in the Fediz configuration.

So what's new in Fediz 1.2.0? The first thing is that it was only possible previously to publish the metadata document when using the Tomcat plugin. In Fediz 1.2.0, this has been extended to cover the other plugins, i.e. Jetty, Spring, etc. In addition, the forthcoming Fediz 1.2.1 release adds support for Metadata to the IdP. The Metadata is available at the same standard URL as for the RP, e.g.:

This signed document describes the URL of the STS, as well as that of the IdP itself, and the claims that are offered by the IdP.

Friday, July 17, 2015

(Slightly) Faster WS-Security using MTOM in Apache CXF 3.1.2

A recent issue was reported at Apache CXF to do with the inability to process certain WS-Security requests that were generated by Metro or .NET when MTOM was enabled. In this case, Metro and .NET avoid BASE-64 encoding bytes and inserting them directly into the message (e.g. for BinarySecurityTokens or the CipherValue data associated with EncryptedData or EncryptedKey Elements). Instead the raw bytes are stored in a message attachment, and referred to in the message via xop:Include. Support for processing these types of requests has been added for WSS4J 2.0.5 and 2.1.2.

In addition, CXF 3.1.2 now has the ability to avoid the BASE-64 encoding step when creating requests when MTOM is enabled, something that we will look at in this post. The advantage of this is that is marginally more efficient due to avoiding BASE-64 encoding at the sending side, and BASE-64 decoding on the receiving side.

1) Storing message bytes in attachments in WSS4J

A new WSS4J configuration property has been added in WSS4J 2.0.5/2.1.2 to support storing message bytes in attachments. This property is used when configuring WS-Security via the "action" based approach in CXF:
  • storeBytesInAttachment: Whether to store bytes (CipherData or BinarySecurityToken) in an attachment. The default is false, meaning that bytes are BASE-64 encoded and "inlined" in the message.
WSS4J is stack-neutral, meaning that it has no concept of what a message attachment actually is. So for this to work, a CallbackHandler must be set on the RequestData Object, that knows how to retrieve attachments, as well as write modified/new attachments out. If you are using Apache CXF then this is taken care for you automatically.

There is another configuration property that is of interest on the receiving side:
  • expandXOPIncludeForSignature: Whether to expand xop:Include Elements encountered when verifying a Signature. The default is true, meaning that the relevant attachment bytes are BASE-64 encoded and inserted into the Element. This ensures that the actual bytes are signed, and not just the reference.
So for example, if an encrypted SOAP Body is signed, the default behaviour is to expand the xop:Include Element to make sure that we are verifying the signature on the SOAP Body. On the sending side, we must have a signature action *before* an encryption action, for this same reason. If we encrypt before signing, then WSS4J will turn off the "storeBytesInAttachment" property, to make sure that we are not signing a reference.

2) Storing message bytes in attachments with WS-SecurityPolicy

A new security configuration property is also available in Apache CXF to control the ability to store message bytes in attachments with WS-Security when WS-SecurityPolicy is used:
  • Whether to store bytes (CipherData or BinarySecurityToken) in an attachment. The default is true if MTOM is enabled.
This property is also available in CXF 3.0.6, but is it is "false" by default. Similar to the action case, CXF will turn off this property by default in either of the following policy cases:
  • If sp:EncryptBeforeSigning is present
  • If sp:ProtectTokens is present. In this case, the signing cert is itself signed, and again we want to avoid signing a reference rather than the certificate bytes.
3) Tests

To see this new functionality in action, take a look at the MTOMSecurityTest in CXF's ws-security systests module. It has three methods that test storing bytes in attachments with a symmetric binding, asymmetric binding + an "action based" approach to configuring WS-Security. Enable logging to see the requests and responses. The encrypted SOAP Body now contains a CipherValue that does not include the BASE-64 encoded bytes any more:

The referenced attachment looks like:

Finally, I wrote a blog post some time back about using Apache JMeter to load-test security-enabled CXF-based web services. I decided to modify the standard symmetric and asymmetric tests, so that the CXF service was MTOM enabled, so that the ability to store message bytes in the attachments was switched on with CXF 3.1.2. The results for both test-cases showed that throughput was around 1% higher when message bytes were stored in attachments. Bear in mind that the change just measures the service creation change, the client request was still non-MTOM aware as it is just pasted into JMeter. So one would expect up to a 4% improvement for a fully MTOM-aware client + service invocation:

Thursday, July 16, 2015

Apache CXF Fediz 1.2.0 tutorial - part IV

This is the fourth in a series of blog posts on the new features and changes in Apache CXF Fediz 1.2.0. The last two articles focused on how clients can authenticate to the IdP in Fediz 1.2.0 using Kerberos and TLS client authentication. In this post we will divert our attention from the IdP for the time being, and look at a new container-independent Relying Party (RP) plugin available in Fediz 1.2.0 based on Apache CXF.

1) RP plugins in Fediz

Apache Fediz ships with a number of RP plugins to secure your web application. These plugins are container-dependent, meaning that if your web app is deployed in say Apache Tomcat, you need to use the Tomcat plugin in Fediz. The following plugins were available prior to Fediz 1.2.0:
The CXF plugin referred to here was not a full WS-Federation RP plugin as in the other modules. Instead, it consisted of a mechanism that allows the SSO (SAML) token retrieved as part of the WS-Federation process to be used by CXF client code, if the web application needed to obtain another token "on behalf of" the other token when making some subsequent web services call.

2) CXF RP plugin in Fediz 1.2.0

In Fediz 1.2.0, the CXF plugin mentioned above now contains a fully fledged WS-Federation RP implementation that can be used to secure a JAX-RS service, rather than using one of the container dependent plugins. Lets see how this works using a test-case:
  • cxf-fediz-federation-sso: This project shows how to use the new CXF plugin of Apache Fediz 1.2.0 to authenticate and authorize clients of a JAX-RS service using WS-Federation.
The test-case consists of two modules. The first is a web application which contains a simple JAX-RS service, which has a single GET method to return a doubled number. The method is secured with a @RolesAllowed annotation, meaning that only a user in roles "User", "Admin", or "Manager" can access the service.

This is enforced via CXF's SecureAnnotationsInterceptor. Finally WS-Federation is enabled for the service via the JAX-RS Provider called the FedizRedirectBindingFilter, available in the CXF plugin in Fediz. This takes a "configFile" parameter, which is a link to the standard Fediz plugin configuration file:

It's as easy as this to secure your CXF JAX-RS service using WS-Federation! The remaining module in the test above deploys the IdP + STS from Fediz in Apache Tomcat. It then takes the "double-it" war above and also deployed it in Tomcat.

Finally, it uses Htmlunit to make an invocation on the service, and checks that access is granted to the service. Alternatively, you can comment the @Ignore annotation of the "testInBrowser" method, and copy the printed out URL into a browser to test the service directly (user credentials: "alice/ecila").

Wednesday, July 15, 2015

Apache CXF Fediz 1.2.0 tutorial - part III

This is the third in a series of blog posts on the new features and changes in Apache CXF Fediz 1.2.0. The previous blog entry described how different client authentication mechanisms are supported in the IdP, and how to configure client authentication via an X.509 certificate, a new feature in Fediz 1.2.0. Another new authentication mechanism in Fediz 1.2.0 is the ability to authenticate to the IdP using Kerberos, which we will cover in this article.

1) Kerberos client authentication in the IdP

Recall that the Apache Fediz IdP in 1.2.0 supports different client authentication methods by default using different URL paths. In particular for Kerberos, the URL path is:
  • /federation/krb -> authentication using Kerberos
The default value for the "wauth" parameter added by the service provider to the request to activate this URL path is:
When the IdP receives a request at the URL path configured for Kerberos, it sends back a request for a Negotiate Authorization header if none is present. Otherwise it parses the header and BASE-64 decodes the Kerberos token and dispatches it to the configured authentication provider. Kerberos tokens are authenticated in the IdP via the STSKrbAuthenticationProvider, which is configured in the Spring security-config.xml

2) Authenticating Kerberos tokens in the IdP

The IdP supports two different ways of validating Kerberos tokens:
  • Passthrough Authentication. Here we do not authenticate the Kerberos token at all in the IdP, but pass it through to the STS for authentication. This is similar to what is done for the Username/Password authentication case. The default security binding of the STS for this scenario requires a KerberosToken Supporting Token. This is the default way of authenticating Kerberos tokens in the IdP.
  • Delegation. If delegation is enabled in the IdP, then the received token is validated locally in the IdP. The delegated credential is then used to get a new Kerberos Token to authenticate the STS call "on behalf of" the original user. 
To enable the delegation scenario, simply update the STSKrbAuthenticationProvider bean in the security-config.xml,
set the "requireDelegation" property to "true", and configure the kerberosTokenValidator property to validate the received Kerberos token: