JavaScript
Article
By Ado Kukic

Easily Migrate Your Existing Users to Auth0

By Ado Kukic

User migration is a dreaded, sometimes unavoidable task that is difficult for developers, inconvenient for users, and expensive for business owners. The need for migrating users from one service or platform to another can stem from any number of reasons: the identity provider you are currently using is shutting down, your organization no longer wishes to manage users themselves, a change in language or framework, and many other reasons.

Auth0 aims to provide the best authentication and identity management platform that is simple and easy for developers to work with. A key feature of the Auth0 platform is the ability to migrate users from any existing data source into Auth0 without inconveniencing users by requiring password changes.

In this tutorial, we’ll take a look at how to do just that. Stormpath is a company that provides authentication as a service and was recently acquired by Okta. Okta has announced that the Stormpath product will be shut down in August 2017 and customers have until then to find a new provider. Let’s see how we can easily migrate existing Stormpath users into Auth0.

User Migration Made Easy with Auth0

Auth0 allows customers to connect to any custom datastore using the custom database connection feature. This feature, as the name may suggest, allows Auth0 to validate user credentials that are stored outside of Auth0. The external data store can be a database such as MySQL, a service like Stormpath, or your own custom implementation. These external data sources are accessed via scripts written in the Auth0 dashboard. The custom database connection feature also allows developers to automatically import users logging in with custom database credentials into Auth0. This feature can be enabled with the flip of a switch.

To implement this feature in the context of migrating Stormpath users to Auth0, we’ll set up a custom database connection and connect it to an existing Stormpath account using the Stormpath API. When your users log in the first time, they will enter their existing Stormpath credentials and, if authenticated successfully, we will automatically migrate that user account from Stormpath into Auth0. Your users will not have to change their password or jump through any additional hoops and you can decide what data to port over from Stormpath. The next time the user logs in, Auth0 will detect that they have been migrated and authenticate them with their Auth0 account.

Migration diagram

To get started, first sign up for a free Auth0 account. We’ll assume that you already have an active Stormpath account with users you wish to migrate. Even if you are not using Stormpath, you can follow along with this tutorial and connect to a different datastore.

Setting up a Custom Database Connection with User Import Functionality

With your account created, let’s set up a custom database connection. In your Auth0 management dashboard, navigate to the database connections section.

Create DB connection

Click on the Create DB Connection button to create a new database connection. You can name your connection anything you like. Leave all the default settings as is for now and click the Create button to create the connection.

Configure DB

Next, let’s go into this database connection and connect it to our Stormpath account. Click on your newly created connection and navigate to the Custom Database tab. Flip the switch titled “Use my own database” and the Database Action Scripts section will now be enabled. This is where we will write our code to connect to your existing Stormpath user datastore.

We will need to write two scripts: Login and Get User. Login will proxy the login process and Get User will manage looking up accounts when a user attempts to reset their password.

Enable custom DB

With our custom database feature turned on, let’s enable the import functionality. By default, the custom database connection will allow us to authenticate with an external database and will not import users to Auth0. If we want to migrate users from the external platform into Auth0 we’ll need to simply toggle a switch. Go to the Settings tab of the connection and flip the switch titled “Import Users to Auth0” and you’re done.

Import to Auth0

One final step we’ll do before implementing our scripts is enabling this connection for our default client. Navigate to the Clients tab while you are in your database connection and flip the switch to enable this client for the Default Connection. If you already have an existing Auth0 account, the connection name may be different.

Enable connection

Login

The Login script is executed when a user attempts to sign in but their account is not found in the Auth0 database. Here we will implement the functionality to pass the user credentials provided to our Stormpath user data store and see if that user is valid. Auth0 provides templates for many common databases such as MongoDB, MySQL and SQL Server, as well as Stormpath. These templates provide a great starting point and you can customize them any way you want or write your own from scratch.

The Database Action Scripts run in a Webtask sandbox and are Node.js scripts. As our tutorial is focused on migrating Stormpath users to Auth0, the scripts shown below will be geared towards working with the Stormpath REST API, but if you are migrating users from a different provider, you would write your implementation here or use one of the other templates provided.

Let’s look at the Login script implementation to see how it works. We will utilize Stormpath’s REST API to authenticate the user.

function login(username, password, callback) {
  // Replace the YOUR-STORMPATH-CLIENT-ID with your Stormpath ID
  var url = 'https://api.stormpath.com/v1/applications/{YOUR-STORMPATH-CLIENT-ID}/loginAttempts';
  // Add your Stormpath API Client ID and Secret
  var apiCredentials = {
    user : 'YOUR-STORMPATH-API-ID',
    password: 'YOUR-STORMPATH-API-SECRET'
  }

  // Stormpath requires the user credentials be passed in as a base64 encoded message
  var credentials = new Buffer(username + ':' + password).toString('base64');

  // Make a POST request to authenticate a user
  request({
    url: url,
    method: 'POST',
    auth: apiCredentials,
    json: {
      type: 'basic',
      // Passing in the base64 encoded credentials
      value: credentials
    }
  }, function (error, response, body) {
    // If response is successful we'll continue
    if (response.statusCode !== 200) return callback();
    // A successful response will return a URL to get the user information
    var accountUrl = body.account.href;

    // Make a second request to get the user info.
    request({
      url: accountUrl,
      auth: apiCredentials,
      json: true
    }, function (errorUserInfo, responseUserInfo, bodyUserInfo) {
      // If we get a successful response, we'll process it
      if (responseUserInfo.statusCode !== 200) return callback();

      // To get the user identifier, we'll strip out the Stormpath API
      var id = bodyUserInfo.href.replace('https://api.stormpath.com/v1/accounts/', '');

      // Finally, we'll set the data we want to store in Auth0 and migrate the user
      return callback(null, {
        user_id : id,
        username: bodyUserInfo.username,
        email: bodyUserInfo.email,
        // We set the users email_verified to true as we assume if they were a valid
        // user in Stormpath, they have already verified their email
        // If this field is not set, the user will get an email asking them to verify
        // their account. You can decide how to handle this for your use case
        email_verified: true
        // Add any additional fields you would like to carry over from Stormpath
      });
    });
  });
}

Get User

The Get User script is executed when the user attempts to do a password reset but their account is not found in the Auth0 database. The Get User script interfaces with your Stormpath datastore and checks to see if the user exists there. If the user does exist, their data is sent back to Auth0 where the user is migrated and a password reset email is sent out from Auth0. Once the user confirms the reset, they are good to go and can access your app. Subsequent logins will be authenticated against the Auth0 database as the user’s profile is now stored with Auth0.

If you are not migrating your user from Stormpath, the Get User script would also be your own implementation. Let’s look at our template implementation of the Get User script for Stormpath:

function getByEmail(email, callback) {
  // Replace the YOUR-STORMPATH-CLIENT-ID with your Stormpath ID
  var url = 'https://api.stormpath.com/v1/applications/{YOUR-STORMPATH-CLIENT-ID}/accounts';
  // Add your Stormpath API Client ID and Secret
  var apiCredentials = {
    user : 'YOUR-STORMPATH-API-ID',
    password: 'YOUR-STORMPATH-API-SECRET'
  };

  // Make a GET request to find a user by email
  request({
    url: url,
    method: 'GET',
    auth: apiCredentials,
    qs: { q: email },
    json: true
  }, function (error, response, body) {
    if (response.statusCode !== 200) return callback();

    var user = body.items[0];

    if (!user) return callback();

    var id = user.href.replace('https://api.stormpath.com/v1/accounts/', '');

    return callback(null, {
      user_id: id,
      username: user.username,
      email: user.email,
      email_verified: true
      // Add any additional fields you would like to carry over from Stormpath
    });
  });
}

With these two scripts, we have user migration setup and ready to go. To test it and make sure our code works, let’s build a simple application that allows a user to log in and request protected resources via an API. We’ll build the frontend with Angular and the backend we’ll power with Spring.

Building the Frontend

We will build our frontend with Angular 2. We’ll use the Auth0 Angular 2 Quickstart to get up and running quickly. Our source code can be found here. Auth0 provides a comprehensive set of quickstarts, SDKs, and guides for many popular languages and frameworks. See them all here.

With the project downloaded, we’ll need to setup our Auth0 credentials. We’ll do that in the auth.config.js file. Open the file and change the values to look like this:

"use strict";
exports.myConfig = {
    // Your Auth0 ClientID.
    clientID: '{AUTH0-CLIENT-ID}',
    // Your Auth0 Domain
    domain: '{YOUR-AUTH0-DOMAIN}.auth0.com'
};

Both of these values can be found in your Auth0 management dashboard. In the dashboard, simply click on the Clients link from the main menu, and select the Default Client that was created when you signed up. If you already had an Auth0 account, select the client that has the database connection with the custom database enabled.

With these values configured save the file and run npm install. Once npm has installed all the required dependencies, run the project by executing npm start. Navigate to localhost:3000 to see the app in action.

App new

Click on the Login button to log in to your application. Clicking the Login button will bring up the Auth0 Lock widget and ask the user to provide their email and password. Here, the user will provide their Stormpath email and password credentials and if they are correct they will be logged in. If you don’t already have a Stormpath user account you can log in with, go into your Stormpath dashboard and create an account. Now login with your Stormpath user credentials.

Auth0 Lock Widget

Notice that you are instantly logged in. If we look at the response data from the transaction we’ll see that the user is coming from the Stormpath-Users connection alongside other data that we imported. Let’s make sure that this user was migrated to Auth0 as well. To check this we’ll navigate to the Users section of the Auth0 dashboard and we’ll now see the user we logged in with.

Migrated users

This means that our migration was successful. This user is now migrated to Auth0. The next time they log in to the application, we’ll check their credentials against Auth0’s database instead of making the extra call to Stormpath. The workflow diagram below illustrates the process once again.

Migration workflow diagram

Now you may notice the two buttons, Call Public API and Call Private API. Let’s build a simple backend that will return data when these links are clicked. We’ll do that next.

Building the Backend

For our backend, we’ll build a simple Spring Boot application that exposes a RESTful API. You can get the code for the sample application here. To setup the application, you will just need to update the application with your credentials. The file where the credentials are stored is called auth0.properties and can be found in the src/main/resources/ directory.

Edit the file to look like so:

auth0.domain: {YOUR-AUTH-DOMAIN}.auth0.com
auth0.issuer: https://{YOUR-AUTH0-DOMAIN}.auth0.com/
auth0.clientId: {YOUR-AUTH0-CLIENT-ID}
auth0.securedRoute: NOT_USED
auth0.base64EncodedSecret: false
auth0.authorityStrategy: ROLES
auth0.defaultAuth0ApiSecurityEnabled: false
auth0.signingAlgorithm: HS256

With this update in place, you should be able to build the application by running:

mvn spring-boot:run -Drun.arguments="--auth0.secret=YOUR_SECRET_KEY"

If the application was built successfully, you will be able to access the API at localhost:4000. The two routes that are exposed by this application that we care about are /public and /secure. The /public route will be accessible by everyone, while the /secure route will return a successful response only if the user is authenticated and passes the correct credentials.

Public API

Once your backend is up and running, go back to your frontend application and try clicking on the the two links, Call Public API and Call Private API. The public API you will be able to access even when not logged in. For the private API, you will need to be logged in to call the route and get the appropriate response.

Private API

We also used Angular 2 to add some dynamic classes. So if the user is logged in we’ll make both of the buttons green to indicate they can be clicked.

App logged in

Go Further with Auth0

I hope the user migration functionality I showed in this article helps with your use case. This gradual migration works great because it is transparent to your end-users. In cases where you don’t have the luxury of doing a gradual migration, you can bulk import your existing user data store into Auth0. Additionally, since we already wrote the Get User script you can send out a mass email to your users letting them know they need to change their password and by clicking on the link in the email their accounts will be migrated to Auth0.

Now that your migration woes have been taken care of, let’s briefly talk about what Auth0 brings to the table besides authentication, authorization, and user migration. Many features that Auth0 provides can be enabled with the flip of a switch. Multifactor authentication is one such feature. You can enable MFA using our in-house MFA solution, Guardian, with just the flip of a switch.

If you are already using a 3rd party MFA solution or have your own custom solution, you can continue to use it as well. The Auth0 Rules extensibility platform allows you to take control of the authorization workflow. Here you can configure any number of events such as triggering 3rd party MFA, performing progressive profiling, and much more.

Auth0 provides traditional username and password authentication, social connections to over 50 social networks including Google, Facebook, and Twitter, as well as enterprise connections through Active Directory, SAML, Google Apps, and more.

Conclusion

The custom database connection and import user functionality give developers an easy way to migrate their existing users to Auth0. Whether those users reside with Stormpath or a different provider, implementing just two scripts to connect to the datastore is all that’s needed. Even as your users are slowly migrating, you can take advantage of all the other features Auth0 offers like multifactor authentication, anomaly detection, and more.

If you are affected by the Stormpath news or are looking to migrate your users for a different reason and want it done painlessly, give Auth0 a try, sign up for a free account and get started today.

  • Shahroze Nawaz

    That is a nice and easy overview of using Auth0 for authentication. This a time savior to implement Auth0 instead of custom developed authentication system.

  • Lincoln Turner

    Can you recommend any developers that I can hire to migrate my users from Stormpath to Auth0?

Recommended
Sponsors
Get the latest in JavaScript, once a week, for free.