Written by
  • email
  • twitter
  • linkedin
  • linkedin

The REST interface of Apache Syncope 2.0 offers full access to IdM features, but what if you need to extend?

The REST layer in the Core module of Apache Syncope 2.0 is the result of an intense, finishing and evolving work around the strong, Apache CXF-based foundations provided by earlier versions. What is now available is a fully-compliant JAX-RS 2.0 implementation, natively dealing both with JSON and XML payloads. Moreover, an extension can be enabled to instantly benefit from Swagger integration.

Identity Management, however, is a process claiming the maximum flexibility from its tools: for this reason I am going to show in the following how the standard set of REST services can be simply extended with custom operations. This as practical application of the advices provided by the official reference guide.

The use case

This comes from a recent discussion in the public user mailing list of the Apache Syncope project: a reminder which, upon providing a registered e-mail address, sends out a message to such address, containing the matching username.

The project

The Maven project from this post, with the full source code, is hosted at Github for convenience.

After generating a new Maven project, in order to create a Syncope extension, I have prepared the following module structure:

ext
└── reminder
    ├── rest-api
    ├── rest-cxf
    └── logic

In order to define a new REST endpoint, three components are essentially needed (please note how this follows the Syncope's architectural pattern):

  1. a JAX-RS annotated interface
  2. a CXF-enabled implementation of such interface
  3. a Logic class featuring the actual implementation logic

In the sample project, the JAX-RS annotated interface is ReminderService:

@Path("users/reminder")
public interface ReminderService extends JAXRSService {

    /**
     * Sends an e-mail with his / her username to the user identified by the provided e-mail address.
     *
     * @param email e-mal address identifying a given user
     */
    @GET
    void remindUsername(@NotNull @QueryParam("email") String email);
}

A single endpoint is defined here, but more can be added.

The CXF-enabled implementation is ReminderServiceImpl:

@Service
public class ReminderServiceImpl extends AbstractServiceImpl implements ReminderService {

    @Autowired
    private ReminderLogic logic;

    @Override
    public void remindUsername(final String email) {
        logic.remindUsername(email);
    }

}

Here the code just passes the invocation down the line to the Logic class; more checks and modifications, specific to the REST / HTTP domain, can be performed as parsing / returning header values, for example.

Finally the actual logic is implemented by ReminderLogic:

    @PreAuthorize("isAnonymous() or hasRole('" + StandardEntitlement.ANONYMOUS + "')")
    public void remindUsername(final String email) {
        AttributeCond emailCond = new AttributeCond(AttributeCond.Type.EQ);
        emailCond.setSchema("email");
        emailCond.setExpression(email);

        List<User> matching = searchDAO.search(SearchCond.getLeafCond(emailCond), AnyTypeKind.USER);
        if (matching.isEmpty()) {
            throw new NotFoundException("User with e-mail address " + email);
        }
        if (matching.size() > 1) {
            LOG.error("Multiple users with e-mail address {}: {}", email, matching);
            throw new IllegalArgumentException("Multiple users with e-mail address " + email);
        }

        User user = matching.get(0);

        notificationManager.createTasks(
                AuditElements.EventCategoryType.CUSTOM,
                null,
                null,
                "remindUsername",
                AuditElements.Result.SUCCESS,
                binder.getUserTO(user, false),
                null);
    }

This code essentially:

  1. restricts the invokers to anonymous users by mean of Spring Security annotations and Syncope entitlements
  2. finds the internal user marching the provided e-mail address (and throws exceptions for anything unexpected)
  3. triggers a specific notification event

The last item requires a notification matching that event and a specific mail template to be configured in the system: these things were added to the default content so that they are bootstrapped with embedded mode.

How to test

Assuming to have GIT and Maven properly configured:

$ git clone https://github.com/ilgrosso/syncopeNewRESTEndpoint.git
$ mvn clean install
$ cd enduser
$ mvn -Pembedded

At this point the new REST endpoint is visible both from the REST reference (point your favorite browser to http://localhost:9080/syncope/):

and Swagger UI (point to http://localhost:9080/syncope/swagger/):

Want to do more?

REST endpoints can do much more in Syncope:

  • accept / return transfer objects, which will be transparently handled as JSON or XML;
  • persist new entities into the internal storage;
  • enrich the Admin Console with new features.

The Apache Camel Provisioning Manager can be taken as reference as it implements everything an extension is meant for.


Don't struggle any more with rigid, unmodifiable Identity Managers (proprietary or Open Source): take your REST with Apache Syncope!

4 VOTIYes, Excellent!Yes, Excellent!
Ti è stato utile questo articolo?
From Tirasa's Blog
The place where we share what we do, learn and discover day by day.
Go to blog >