Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Simplify Authentication and User Management with Mule and Stormpath

DZone's Guide to

Simplify Authentication and User Management with Mule and Stormpath

· Integration Zone
Free Resource

Modernize your application architectures with microservices and APIs with best practices from this free virtual summit series. Brought to you in partnership with CA Technologies.

Originally authored by David Dossot

The dreaded user table. Think about it: whenever you start working on a new end-user application, you’ll have to create a table to store emails, user information and passwords. And then you’ll need to add support for the password reset workflow. And so on and so forth. The wheel gets re-invented time and again. Of course, you may go sophisticated and decide to manage users in LDAP or even – gasp – ActiveDirectory. Now you would have a whole different range of problems to deal with, starting with interacting with this external directory in a graceful manner.

Enter Stormpath, the SaaS API whose sole mission is to make authentication and user management awesome and developer friendly! And thanks a new connector for Mule (available here), you can now benefit from Stormpath’s extensive features, which include all of the aforementioned ones, and many more.

In this post, we will look at a Mule application that integrates with the Stormpath API via this new connector. This application exposes a web user interface that uses AJAX to interact with the Mule application. This application allows a user to create an account, log-in and trigger the password forgotten procedure. Enough ado, let’s start digging!

Note that the complete source code of this demo application is available on-line at https://github.com/mulesoft/stormpath-demo

Overview

You may right away be wondering why do we need an application between the web browser and the Stormpath API? Why can’t the browser directly connect to the API? There is no technical hindrance to doing so but there are really serious reasons for not doing that:

  • The Stormpath API is secured: the application using it has to use a key/secret pair to authenticate itself. You do not want to disseminate these keys/secrets by storing them on the client side, thus giving access to your user data to the world wide web.
  • The Stormpath API is feature rich: you want to restrict the range of what the web user interface can do, and an intermediary application exposes only what is needed.
  • Orchestration is power: using a Mule application as the intermediary opens the door for orchestrating Stormpath operations, as we will see in the first flow we will look at.

Let’s now take a look at the three main flows that the Mule application contains.

Create Account Flow

This first flow is the most complex one: it demonstrates how user provisioning is done in our application:

  • We first extract the new account information details from the inbound HTTP request,
  • We create a Stormpath account object from this information,
  • We then use the “Create Account” operation from the Stormpath API.
  • If no exception has been raised, the flow continues with the user provisioning which, in our case, consists inof asynchronously creating bug tracking and CRM accounts.
  • We use the JSON representation of the created Stormpath account as the body of the HTTP response.

We do not need to validate the data sent by the user as this validation will be performed by the Stormpath API. It will ensure all the mandatory fields are present and that the password complies to a strict policy. In case anything is wrong with the data sent by the user, the Mule connector will throw an exception, based on the error message received from the API. What you don’t see here is the custom exception strategy we have in place that extracts the error message and returns it as JSON to the web UI.

Attempt Login Flow

This flow allows the web UI to validate that the user credentials (user name and password) are correct:
  • Again, we first extract the user credentials from the inbound HTTP request,
  • We create the Stormpath attempt login request object,
  • Then we invoke the Stormpath API,
  • We use its response represented as JSON as the HTTP response.

Again the custom exception we’ve mentioned in the first flow is in effect so any error would be caught and properly returned as JSON to the web UI.

Note that we do not cover the management of web sessions in this example. Should we need web sessions, we would generate a unique ID right after the call to Stormpath’s “Attempt Login” operation, and store it in an expirable data structure (like the ones provided by Redis). This unique ID would become the key shared with the web UI and used by Mule to retrieve the web session data from the data store.

Password Reset Flow

Our last flow allows a user to initiate the password forgotten procedure:

  • Once again, we first extract the user email from the inbound HTTP request,
  • We create the Stormpath “create password reset token” request object,
  • We then call the Stormpath API,
  • We use its response represented as JSON for the HTTP response.

Stormpath takes care of emailing the user with a reset password link so really this flow is just acting as a basic trigger.

Web User Interface

Mule is able to serve static resources over HTTP so it can fully serve the above UI. The Mule application is now a fully self contained AJAX-powered web UI that interacts with Stormpath for user provisioning and authentication.

So never create a user table again… thanks to these two great heavy lifters that are Mule and Stormpath! You can get started now by visiting: http://www.mulesoft.org/connectors/stormpath-connector

The Integration Zone is proudly sponsored by CA Technologies. Learn from expert microservices and API presentations at the Modernizing Application Architectures Virtual Summit Series.

Topics:

Published at DZone with permission of Ross Mason, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}