January 27, 2014

Features coming in Fediz 1.2 - REST

The work for Fediz 1.2 has started and introduces a bunch of new features for the IDP. This post shall introduce the new features to initiate the discussion (recommended in the CXF Dev Mailing list) now. These features become available in the new minor release. Therefore, the branch trunk is has been changed to this version. The new features are:
  • Single Logout

    The IDP supports to logout from all web applications in one click according the WS-Federation specification

  • REST interface and JPA persistence store

    Configure your IDP, its relying parties (applications) and Trusted IDPs using a REST interface and make the configuration persistent in a database instead of using Spring configuration files.

This blog focus on the new REST interface and the persistence layer using JPA.

The current release version of the IDP is configured with spring configuration files which is fine for static configurations. If you make a change to support new claims or register a new relying party (web application) you have to update the spring configuration file of the fediz-idp WAR and redeploy. Therefore, the IDP has been enhanced to provide a REST interface to manage the IDP(s), its trusted IDPs, the applications and the claims for each application as well as for the IDP. The data is persistet using JPA. The complexity of the IDP is increased due to the requirement of a database but you can also use a database like H2 or HSQL which supports to launch the database embedded. The following picture illustrates the class diagram and its relationships:

As you notice, all relationships are aggregations which means the lifecycle of application has no dependency to the claims. The relationship between application and claim is specical because depending on the relation an claim is optional or mandatory.

REST Interface

The classes in the above class diagram map to root level resources which are independently managed (create, read, update, delete).

Base URL: https://:/fediz-idp/services/rs

Resource Claim

/claims

  • GET

      Returns all resources for Claim. This is a collection and can be filtered (see below)

      Request

      • N.A.
      Response
      • 200 (OK)

        Response Body:

           <ns2:claims xmlns:ns2="http://org.apache.cxf.fediz/">
              <ns2:claim>
                 <claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postal</claimType>
              </ns2:claim>
              <ns2:claim>
                 <claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surename</claimType>
              </ns2:claim>
           </ns2:claims>
        
      • 500 (Error)
  • POST

      Create a new Claim resource

      Request

         <ns2:claim xmlns:ns2="http://org.apache.cxf.fediz/">
            <claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postal</claimType>
         </ns2:claim>
      
      Response
      • 201 (Created)

        Response Body: The created resource.

        Response Header: Location contains the URL of the created resource.

      • 500 (Error)
/claims/{claimType}
  • GET

      Get the claim with the requested claimType

      Request

      • N.A.
      Response
      • 200

        Response Body: The claim with the requested claimType

      • 500 (Error)
      • 404 (Not found)
  • PUT

      Update the claim with PathParam claimType

      Request

         <ns2:claim xmlns:ns2="http://org.apache.cxf.fediz/">
            <claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postal</claimType>
            <displayName>Postal</displayName>
         </ns2:claim>
      
      Response
      • 204 (No Content)
      • 500 (Error)
  • DELETE

      Delete the claim with the claimType passed as PathParam

      Request

      • N.A.
      Response
      • 204 (NoContent)
      • 500 (Error)

Resource Application

/applications

  • GET

      Returns all resources for Application. This is a collection and can be filtered (see below)

      Request

      • N.A.
      Response
      • 200 (OK)

        Response Body:

           <applications xmlns:ns2="http://org.apache.cxf.fediz/">
              <ns2:application id="100">
                 <realm>urn:org:apache:cxf:fediz:fedizhelloworld</realm>
                 <role>ApplicationServiceType</role>
                 <serviceDisplayName>Fedizhelloworld</serviceDisplayName>
                 ...
        
      • 500 (Error)
  • POST

      Create a new Application resource

      Request

         <ns2:application xmlns:ns2="http://org.apache.cxf.fediz/">
            <realm>urn:org:apache:cxf:fediz:newapp</realm>
            <role>ApplicationServiceType</role>
            <serviceDisplayName>Fedizhelloworld new</serviceDisplayName>
      
      Response
      • 201 (Created)

        Response Body: The created resource.

        Response Header: Location contains the URL of the created resource.

      • 500 (Error)
/applications/{realm}
  • GET

      Get the application with the requested realm

      Request

      • N.A.
      Response
      • 200

        Response Body: The application with the requested realm

      • 500 (Error)
      • 404 (Not found)
  • PUT

      Update the application with PathParam realm

      Request

         <ns2:application xmlns:ns2="http://org.apache.cxf.fediz/">
            <realm>urn:org:apache:cxf:fediz:newapp</realm>
            <role>ApplicationServiceType</role>
            <serviceDisplayName>Fedizhelloworld new</serviceDisplayName>
            ...
      
      Response
      • 204 (No Content)
      • 500 (Error)
  • DELETE

      Delete the application with the realm passed as PathParam

      Request

      • N.A.
      Response
      • 204 (NoContent)
      • 500 (Error)
/applications/{realm}/claims
  • POST

      Add a relationship (aggregation) between the application realm to an existing claim

      Request

         <ns2:requestClaim xmlns:ns2="http://org.apache.cxf.fediz/">
            <claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname</claimType>
            <optional>false</optional>
         </ns2:requestClaim>
      
      Response
      • 201 (No Content)
      • 409 (Conflict)

        If the claim is already added to the resource

      • 500 (Error)
/applications/{realm}/claims/{claimType}
  • DELETE

      Delete the relationship (aggregation) between resource Application with the realm and the Sub-Resource claim

      Request

      • N.A.
      Response
      • 204 (NoContent)
      • 500 (Error)

Resource TrustedIdp

/trusted-idps

  • Trusted IDP has got the same methods like the Resource Claim and Application
/trusted-idps/{realm}
  • Trusted IDP has got the same methods like the Resource Claim and Application

Resource Idp

/idps

  • IDP has got the same methods like the other resources
/idps/{realm}
  • IDP has got the same methods like the other resources
/idps/{realm}/claims
  • POST

      Add a relationship (aggregation) between the resource Idp with the realm to an existing claim

      Request

         <ns2:Claim xmlns:ns2="http://org.apache.cxf.fediz/">
            <claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname</claimType>
         </ns2:Claim>
      
      Response
      • 204 (No Content)
      • 409 (Conflict)

        If the claim is already added to the resource

      • 500 (Error)
/idps/{realm}/claims/{claimType}
  • DELETE

      Delete the relationship (aggregation) between resource Idp with the realm and the Sub-Resource claim

      Request

      • N.A.
      Response
      • 204 (NoContent)
      • 500 (Error)
/idps/{realm}/applications
  • POST

      Add a relationship (aggregation) between the resource Idp with the realm to an existing resource Application

      Request

         <ns2:Application xmlns:ns2="http://org.apache.cxf.fediz/">
            <realm>urn:org:apache:cxf:fediz:newapp</realm>
         </ns2:Application>
      
      Response
      • 204 (No Content)
      • 409 (Conflict)

        If the application is already added to the resource

      • 500 (Error)
/idps/{realm}/applications/{applicationRealm}
  • DELETE

      Delete the relationship (aggregation) between resource Idp with the realm and the Sub-Resource Application passed in applicationRealm

      Request

      • N.A.
      Response
      • 204 (NoContent)
      • 500 (Error)
/idps/{realm}/trusted-idps
  • POST

      Add a relationship (aggregation) between the resource Idp with the realm to an existing resource TrustedIdp

      Request

         <ns2:TrustedIdp xmlns:ns2="http://org.apache.cxf.fediz/">
            <realm>urn:org:apache:cxf:fediz:idp:realm-B</realm>
         </ns2:TrustedIdp>
      
      Response
      • 204 (No Content)
      • 409 (Conflict)

        If the trusted IDP is already added to the resource

      • 500 (Error)
/idps/{realm}/trusted-idps/{trustedIdpRealm}
  • DELETE

      Delete the relationship (aggregation) between resource Idp with the realm and the Sub-Resource TrustedIdp passed in trustedIdpRealm

      Request

      • N.A.
      Response
      • 204 (NoContent)
      • 500 (Error)

Additional features of the REST interface

  • JSON Support

    By adding .json as a suffix to the URL you can enforce to get a JSON representation back instead of the default XML representation

  • Filter entries on collections (paging)

    The query parameters start and size allow you to define (default, 0, 5)

  • Query parameter expand

    As of now, sub-resources are embedded in the response by default. But I'm considering to not return all sub-resources by default when hypermedia support is added to the REST interface. Hypermedia will return link URLs where the sub-resources can be resolved

The following example illustrates how the sub-resource Claim is embedded in the resource Application.
<ns2:application id="100" xmlns:ns2="http://org.apache.cxf.fediz/">
   <realm>urn:org:apache:cxf:fediz:fedizhelloworld</realm>
   ...
   <claims>
      <ns2:requestClaim id="100">
         <claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname</claimType>
         <description>Description for firstname</description>
         <displayName>firstname</displayName>
         <optional>true</optional>
      </ns2:requestClaim>
The resource Application supports the values claims and all for the query parameter expand and the resource Idp supports the values claims, trusted-idps and applications. You can also send several values for the query parameter expand as illustrated in the following example:
?expand=claims&expand=applications

What is missing in the current SNAPSHOT version

The following features are missing in the current SNAPSHOT version:
  • Single Log Out (Patch applied to JIRA request)
  • Authentication support for REST interface
  • Hypermedia support for REST interface

Note

As you noticed, the IDP supports a collection of IDPs. This is by intention even the current version doesn't support several realms in one IDP whereas the feature is already supported by the STS. This is planned in the next release.

In smaller companies you might have only one Identity Store whereas in bigger companies you probably have more than one Identity Store. To avoid deploying each IDP realm in a different Servlet Contexts the Fediz IDP will support several IDPs in one deployment. The realms are differentiated by the URL which is addressed by property uri in the future.

Testing

You can either start the IDP standalone (Jetty Maven Plugin) or within a pre-configured Tomcat Container.

Standalone deployment

The easiest approach to test the new IDP is checking out the sources as described in section Building here and build from the project root directory:
mvn clean install
Then run within the sub-directory services/idp the following Maven command:
mvn jetty:run-war
This command will start the Jetty container and deploy the IDP in there. The database used in HSQL and the default HTTPS port is 9443 and HTTP is 9080. You can overwrite the ports with the Maven properties idp.https.port and idp.http.port as illustrated here:
mvn jetty:run-war -Didp.https.port=8443

Tomcat Deployment

The fediz-idp.war does NOT ship the JDBC driver JAR. Be sure to deploy it under $CATALINA_HOME/lib. If you don't update the persistence.properties the default database is HSQL. You can also define the datasource on the Container Level if you like under the JNDI name java:comp/env/jdbc/fedizDataSource.

soapUI Test

After you started the IDP you can import the WADL (WADL is the counterpart of a WDSL for Web Services) which can be accessed at the following URL (assumption: you started the IDP with the defaults):
https://localhost:9443/fediz-idp/services/rs?_wadl

Summary

The REST interface is in early stage and subject to change. It's very important to have a stable REST interface for future. As the current IDP doesn't provide a Web-UI yet, you can build your own Web-UI and use the REST interface to administer the behaviour of the Fediz IDP. Therefore, it's very important to get a stable REST interface without requiring changes in your Web-UI with each new Fediz IDP release.

Please provide feedback to the CXF Dev Mailing list to discuss the feedback in broader audience.