Friday, September 18, 2015

Support for Jetty 9 in Apache CXF Fediz 1.3.0

Yesterday I gave a tutorial on how to deploy the Apache CXF Fediz simpleWebapp example to Jetty 8 using Fediz 1.2.1. Apache CXF Fediz 1.3.0 will ship with a new plugin to support Jetty 9. In this post I will cover how to deploy the simpleWebapp example to Jetty 9 using this new plugin.

1) Deploying the 1.2.0 Fediz IdP in Apache Tomcat

As per the previous tutorial on deploying to Tomcat, we will deploy the IdP and STS in Apache Tomcat. Download Fediz and extract it to a new directory (${fediz.home}). To deploy the IdP to Tomcat:

  • Copy ${fediz.home}/idp/war/* to ${catalina.home}/webapps
  • Download and copy the hsqldb jar (e.g. hsqldb-1.8.0.10.jar) to ${catalina.home}/lib
  • Copy idp-ssl-key.jks and idp-ssl-trust.jks from ${fediz.home}/examples/samplekeys to ${catalina.home}.
  • Edit ${catalina.home}/conf/server.xml and change the ports from 8080 -> 9080 + 8443 -> 9443 so as not to conflict with Jetty.
  • Edit the TLS Connector in ${catalina.home}/conf/server.xml' as well, e.g.: <Connector port="9443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="want" sslProtocol="TLS" keystoreFile="idp-ssl-key.jks" keystorePass="tompass" keyPass="tompass" truststoreFile="idp-ssl-trust.jks" truststorePass="ispass" />
Now start Tomcat, and check that the IdP is live by opening the STS WSDL in a web browser: 'https://localhost:9443/fediz-idp-sts/REALMA/STSServiceTransport?wsdl'

2) Deploying the simpleWebapp in Jetty 9

Download Jetty 9 and extract it to a new directory (${jetty.home}). First let's set up TLS:
  • Copy ${fediz.home}/examples/samplekeys/rp-ssl-key.jks to ${jetty.home}/etc
  • Copy ${fediz.home}/examples/samplekeys/ststrust.jks to ${jetty.home} *and* to ${jetty.home}/etc
  • Edit ${jetty.home}/start.ini to include the ssl, https and fediz modules, and set up the TLS configuration as follows:
  •  The "fediz" module referred to above must be placed in ${jetty.home}/modules/fediz.mod with content:
Now we will deploy the simpleWebapp:
  • Copy ${fediz.home}/examples/simpleWebapp/src/main/config/fediz_config.xml to ${jetty.home}/etc
  • Do a "mvn clean install" in ${fediz.home}/examples/simpleWebapp
  • Copy ${fediz.home}/examples/simpleWebapp/target/fedizhelloworld.war to ${jetty.home}/webapps
  • Create a new directory: ${jetty.home}/lib/fediz
  • Copy ${fediz.home}/plugins/jetty9/lib/* to ${jetty.home}/lib/fediz (note you may want to copy in a slf4j logging binding in here to see logging output, e.g. slf4j-jdk14-1.7.12.jar).
  • Create a new file in ${jetty.home}/webapps called "fedizhelloworld.xml" with content as follows, and then start Jetty as normal: 

3) Testing the service

To test the service navigate to:
  • https://localhost:8443/fedizhelloworld/  (this is not secured) 
  • https://localhost:8443/fedizhelloworld/secure/fedservlet
With the latter URL, the browser is redirected to the IDP (select realm "A") and is prompted for a username and password. Enter "alice/ecila" or "bob/bob" or "ted/det" to test the various roles that are associated with these username/password pairs.

Thursday, September 17, 2015

Deploying the Apache CXF Fediz simpleWebapp to Jetty

On previous tutorials about Apache CXF Fediz, I have always described deploying the simpleWebapp example that ships with Fediz in Apache Tomcat. However, Fediz also supports deploying secured applications in Jetty (7 and 8 as of yet, support for Jetty 9 is forthcoming). As it can be somewhat confusing setting up the security requirements correctly, I will cover briefly how to deploy the simpleWebapp in Jetty 8 in this blog post (see the Fediz wiki for a dedicated page on deploying to Jetty).

1) Deploying the 1.2.0 Fediz IdP in Apache Tomcat

As per the previous tutorial on deploying to Tomcat, we will deploy the IdP and STS in Apache Tomcat. Download Fediz 1.2.1 and extract it to a new directory (${fediz.home}). To deploy the IdP to Tomcat:
  • Copy ${fediz.home}/idp/war/* to ${catalina.home}/webapps
  • Download and copy the hsqldb jar (e.g. hsqldb-1.8.0.10.jar) to ${catalina.home}/lib
  • Copy idp-ssl-key.jks and idp-ssl-trust.jks from ${fediz.home}/examples/samplekeys to ${catalina.home}.
  • Edit ${catalina.home}/conf/server.xml and change the ports from 8080 -> 9080 + 8443 -> 9443 so as not to conflict with Jetty.
  • Edit the TLS Connector in ${catalina.home}/conf/server.xml' as well, e.g.: <Connector port="9443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="want" sslProtocol="TLS" keystoreFile="idp-ssl-key.jks" keystorePass="tompass" keyPass="tompass" truststoreFile="idp-ssl-trust.jks" truststorePass="ispass" />
Now start Tomcat, and check that the IdP is live by opening the STS WSDL in a web browser: 'https://localhost:9443/fediz-idp-sts/REALMA/STSServiceTransport?wsdl'

2) Deploying the simpleWebapp in Jetty 8

Download Jetty 8 and extract it to a new directory (${jetty.home}). First let's set up TLS:
  • Copy ${fediz.home}/examples/samplekeys/rp-ssl-key.jks to ${jetty.home}/etc
  • Copy ${fediz.home}/examples/samplekeys/ststrust.jks to ${jetty.home} *and* to ${jetty.home}/etc
  • Edit ${jetty.home}/start.ini and make sure that 'etc/jetty-ssl.xml' is included.
  • Edit ${jetty.home}/etc/jetty-ssl.xml and configure the TLS keys, e.g.:


Now we will deploy the simpleWebapp:
  • Copy ${fediz.home}/examples/simpleWebapp/src/main/config/fediz_config.xml to ${jetty.home}/etc
  • Do a "mvn clean install" in ${fediz.home}/examples/simpleWebapp
  • Copy ${fediz.home}/examples/simpleWebapp/target/fedizhelloworld.war to ${jetty.home}/webapps
  • Create a new directory: ${jetty.home}/lib/fediz
  • Copy ${fediz.home}/plugins/jetty/lib/* to ${jetty.home}/lib/fediz (note you may want to copy in a slf4j logging binding in here to see logging output, e.g. slf4j-jdk14-1.7.12.jar).
  • Edit ${jetty.home}/start.ini and add "fediz" to "OPTIONS".
  • Create a new file in ${jetty.home}/contexts called "fedizhelloworld.xml" with content as follows, and then start Jetty as normal:

3) Testing the service

To test the service navigate to:
  • https://localhost:8443/fedizhelloworld/  (this is not secured) 
  • https://localhost:8443/fedizhelloworld/secure/fedservlet
With the latter URL, the browser is redirected to the IDP (select realm "A") and is prompted for a username and password. Enter "alice/ecila" or "bob/bob" or "ted/det" to test the various roles that are associated with these username/password pairs.

Tuesday, September 8, 2015

Authorization for web services using XACML 3.0

In a blog post last year, I covered some authentication and authorization test-cases for Apache CXF-based web services that I uploaded to github. In particular, the cxf-sts-xacml demo showed how a CXF service can use XACML to authorize a web service request, by sending a XACML request to a Policy Decision Point (PDP) and then by enforcing the authorization decision. This demo only covered XACML 2.0 (provided by OpenSAML). In this post we will give an example of how to use XACML 3.0 via Apache OpenAz to make and enforce authorization requests for Apache CXF based services.

1) Introducing Apache OpenAz

The XACML functionality in Apache CXF is based on OpenSAML, which provides support for XACML 2.0. However, XACML 3.0 is an OASIS standard as of January, 2013. A new project in the Apache Incubator called Apache OpenAz addresses this gap. The source code is broken down into the following modules:
  • openaz-xacml - API + common functionality.
  • openaz-xacml-rest - Some common functionality used by the RESTful API interfaces
  • openaz-xacml-pdp - A PDP implementation
  • openaz-xacml-pdp-rest - An implementation of the XACML 3.0 RESTful Interface for the PDP
  • openaz-xacml-pap-rest - An implementation of the XACML 3.0 RESTful Interface for the PAP
  • openaz-xacml-test - Some testsuites
  • openax-pep -  The PEP (Policy Enforcement Point) implementation.
2) Integrating Apache OpenAz with Apache CXF

The testcases are available here:
  • cxf-sts-xacml: This project contains a number of tests that show how to use XACML with CXF to authorize a client request. It contains both XACML 2.0 tests and XACML 3.0 tests.
In both cases, the client obtains a SAML Token from the STS with the roles of the client embedded in the token. The service provider extracts the roles, and creates a XACML request. For the XACML 2.0 case, OpenSAML is used to create a XML XACML 2.0 request. This is then sent to a mocked PDP JAX-RS service. However, let's focus on the XACML 3.0 case. In this test, the OpenAz API (via the openaz-xacml module as covered above) is used to create a JSON XACML 3.0 request. This is evaluated by a OpenAz-based PDP which is co-located with the service. After evaluating the request, the PDP response is then enforced at the service side.

The service endpoint is configured in Spring as follows, registering a XACML3AuthorizingInterceptor (which in turn contains a reference to the co-located PDP):

The XACML3AuthorizingInterceptor is configured with a implementation to create a XACML 3.0 request using the SAML 2.0 profile of XACML 3.0, which is subsequently converted into JSON + sent to the PDP. The PDP is configured with "root" and "reference" policies, that state that a user of role "boss" has permission to "execute" the Web Service Operation "{http://www.example.org/contract/DoubleIt}DoubleItService#DoubleIt". For example:
A sample authorization request looks like:
If you are interested in XACML 3.0 please get involved with the Apache OpenAz project! Once the project gets more mature, the PEP code in my project will probably make it over to Apache CXF so that users have the option of supporting XACML 2.0 or 3.0 (and XML or JSON) with their web services.

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/users.properties". 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.