Tuesday, August 20, 2013

Apache Syncope tutorial - part IV

In the first tutorial on Apache Syncope, we showed how to deploy Syncope to Apache Tomcat, using MySQL as the internal storage mechanism. In the second and third tutorials, we showed how to import some users and roles into Syncope from database and directory backend resources. In this tutorial, we will show how an external client can query Syncope's REST API for the purposes of authentication and authorization. This tutorial assumes that Syncope is set up as described in tutorial I, and that Users + Roles have been imported as per tutorials II and III.

1) Syncope's REST API

Apache Syncope exposes its functionality via a rich REST API. Apache Syncope 1.1 features a new REST API, which is powered by Apache CXF. The new API has been created with the aim of applying RESTful best practices.

2) Querying Syncope's REST API

I've created some simple test-cases (hosted on github) based around a CXF SOAP client/service invocation, which show how to use Syncope's REST API for authentication and authorization.

a) Authentication

The Authentication test uses Syncope as an IDM for authentication. A CXF client sends a SOAP UsernameToken to a CXF Endpoint. The CXF Endpoint has been configured to validate the UsernameToken via the SyncopeUTValidator, which dispatches the username/passwords to Syncope for authentication via Syncope's REST API. Run the test via:
  • git clone git://github.com/coheigea/cxf-syncope.git
  • cd cxf-syncope
  • mvn test -Dtest=AuthenticationTest
Look at the console output to see how the CXF service dispatches the received Username/Password to Syncope for authentication. 

b) Authorization

The Authorization test uses Syncope as an IDM for authorization. It exploits the fact that we synchronized User's Roles into Syncope in tutorial IV. A CXF client sends a SOAP UsernameToken to a CXF Endpoint. The CXF Endpoint has configured the SyncopeRolesInterceptor, which authenticates the Username/Password to Syncope as per the authentication test. If authentication is successful, it then gets the roles of the user and populates a CXF SecurityContext with the user's name + roles.

The CXF Endpoint has also configured the SimpleAuthorizingInterceptor, which reads the current Subject's roles from the SecurityContext, and requires that a user must have role "boss" to access the "doubleIt" operation ("alice" has this role, "bob" does not). Run the test via:
  • git clone git://github.com/coheigea/cxf-syncope.git
  • cd cxf-syncope
  • mvn test -Dtest=AuthorizationTest


Friday, August 9, 2013

Apache Syncope tutorial - part III

In the first tutorial on Apache Syncope, we showed how to deploy Syncope to Apache Tomcat, and how to set up MySQL as the internal storage mechanism. In the second tutorial, we showed how to import some users into Syncope from a backend (Apache Derby) database resource. In this tutorial, we will look at synchronizing user and role data from an LDAP backend into Syncope, in this case Apache DS. This tutorial assumes that Syncope is set up as described in tutorial I, and that a Surname attribute has been added to the User attributes in Syncope, as described in tutorial II.

1) Apache DS

The basic scenario is that we have a directory that stores user and role information that we would like to import into Apache Syncope. In the previous tutorial, we only imported User data into Syncope. For the purposes of this tutorial, we will work with Apache DS. The first step is to download and launch Apache DS. I recommend installing Apache Directory Studio for an easy way to view the data stored in your directory.

Import the following ldif file into your Apache DS instance. Essentially this describes two users, "cn=alice,ou=users,ou=system" and "cn=bob,ou=users,ou=system", as well as two groups, "cn=employee,ou=groups,ou=system" and "cn=boss,ou=groups,ou=system". Both Alice and Bob are employees, but only Alice is the boss. We will import this user information into Syncope as per tutorial II. However, this time we will go further and import the group information as roles into Syncope. This will enable us to perform authorization checks against Syncope, as will be described in the next tutorial.

2) Synchronize user data into Apache Syncope

The next task is to import (synchronize) the user data from Apache DS into Apache Syncope. See the Syncope wiki for more information on this topic, as well as the following blog post. Launch Apache Syncope as per tutorial I/II.

a) Define a Connector

The first thing to do is to define a Connector. In tutorial I we configured two Connector bundles to use for Syncope, one for a DB backend, and one for an LDAP backend. In this section we select the LDAP Connector, and configure it to connect to the DS instance we have set up above. Go to "Resources/Connectors", and create a new Connector of name "org.connid.bundles.db.ldap". In the "Configuration" tab select:
  • Host: localhost
  • TCP Port: 10389
  • Principal: uid=admin,ou=system
  • Password: <password>
  • Base Contexts: ou=users,ou=system and ou=groups,ou=system
  • LDAP Filter for retrieving accounts: cn=*
  • groupObjectClasses: groupOfNames
  • Group member attribute: member
  • Uid attribute: cn
  • Base Context to Synchronize: ou=users,ou=system and ou=groups,ou=system
  • Object Classes to Synchronize: inetOrgPerson and groupOfNames
  • Status Management Class: org.connid.bundles.ldap.commons.AttributeStatusManagement
  • Tick "Retrieve passwords with search".
In the "Capabilities" tab select the following properties:
  • ONE_PHASE_CREATE
  • ONE_PHASE_UPDATE
  • ONE_PHASE_DELETE
  • SEARCH
  • SYNC
Click on the "helmet" icon in the "Configuration" tab to check to see whether Syncope is able to connect to the backend resource. If you don't see a green "Successful Connection" message, then consult the logs.

b) Define a Resource

Next we need to define a Resource that uses the LDAP Connector.  The Resource essentially defines how we use the Connector to map information from the backend into Syncope Users and Roles. Go into the "Resources" tab and select "Create New Resource". In the "Resource Details" tab select:
  • Name: (Select a name)
  • Connector: (Connector display name you have configured previously)
  • Enforce mandatory condition
  • Propagation Primary
  • Propagation Mode (see here): ONE_PHASE
  • Select "LDAPMembershipPropagationActions" for the "Actions class"
The next step is to create User mappings. Click on the "User mapping" tab, and create the following mappings:

Enable "Account Link" and enter "'cn=' + username + ',ou=users,ou=system'", as shown in the screenshot. The next step is to create Role mappings. Click on the "Role mapping" tab, and create the following mapping:

Enable "Account Link" and enter "'cn=' + name + ',ou=groups,ou=system'" as shown in the screenshot.

c) Create a synchronization task

Having defined a Connector and a Resource to use that Connector, with mappings to map User/Role information to and from the backend, it's time to import the backend information into Syncope.  Go to "Tasks" and select the "Synchronization Tasks" tab. Click on "Create New Task". On the "Profile" tab enter:
  • Name: (Select a name)
  • Resource Name: (The Resource name you have created above)
  • Actions Class: LDAPMembershipSyncActions
  • Create new identities
  • Updated matched identities
  • Delete matching identities
  • Status
  • Full reconciliation
Save the task and then click on the "Execute" button. Now switch to the Users tab. You should see the users stored in the backend, and if you edit a user, you should be able to see what roles are associated with the user. In the "Roles" tab, you should see the imported Roles. For example, here are the roles that are associated with the user "Alice":