Custom Authentication

Table of contents

  1. Introduction
  2. Pryv.io Custom Auth Step
  3. Why using a custom auth step
  4. What is the custom auth step
  5. How to set up the custom auth step
  6. Authenticate data access with Pryv.io
  7. Hands-on example
  8. Custom authentication function
  9. Custom Auth Step features
  10. Authenticate data access with an external service

Introduction

Authentication allows you to validate the identity of a registered user attempting to access resources. You can add a custom authentication step to your Pryv.io platform to verify more information than the authorization token when performing a request to access data.

In this guide, we explain how to provide your Pryv.io platform with this feature and illustrate it with a concrete use case.

Pryv.io Custom Auth Step

Why using a custom auth step

A custom auth step is necessary when you wish to authenticate your Pryv.io API requests or authorize them against another web service. A possible use case can be to verify the identity of the person using the authorization token you have provided him or her with.
In this case, you would append a second token to the Authorization header after the Pryv.io token separated by a whitespace.

For example, if a Alice needs to access data from Bob in your Pryv.io platform, you can implement an authentication step that will allow you to verify the identity of user Alice when she tries to access data from Bob. The identity of the data client (Alice) can be verified through a custom auth step that you can add to your Pryv.io platform as explained below.

What is the custom auth step

You can define a function that will be run by Pryv.io after the authorization token verification.
In this function, you have access to the fields described below, as well as the NodeJS core modules:

// Example of customAuthStepFn.js
module.exports = function (context, callback) {
  // do whatever is needed here (check LDAP, custom DB, etc.)
  performCustomValidation(context, function (err) {
    if (err) { return callback(err); }
    callback();
  });
};

How to set up the custom auth step

For Pryv.io entreprise version, you can add the custom auth step using the admin panel, available on https://adm.DOMAIN. Please request a template version above or equal v1.0.35 to be able to access it.

Authenticate data access with Pryv.io

In this section, we illustrate the usage of a custom auth step through a basic use case. Bob wants to share his data with Alice, and creates an access for her on the stream “Health” with a “read” permission (more information on the Access structure here).

When Alice is using the access that was provided to her, the custom auth step will allow to verify Alice’s identity. This implies the creation of a “verification” access for Alice that will only be used to validate her identity.

Hands-on example

The following scheme explains the different steps of the process using Pryv.io custom auth step.

You can watch the entire flow here.

Bob wants to create an Access exclusive to Alice on his stream “Health” with a “read” permission.

{
  "id": "alices-verification-abc",
  "token": "alices-token-for-bob",
  "type": "shared",
  "name": "alices-access",
  "permissions": [
    {
      "streamId": "verify",
      "level": "read"
    }
  ],
}
{
  "id": "ckdoc7cca0001m1pv5ju4msy5",
  "token": "bobs-token-for-alice",
  "type": "shared",
  "name": "bobs-access-for-alice",
  "permissions": [
    {
      "streamId": "health",
      "level": "read"
    }
  ],
  "clientData": {
    "customAuth": {
      "PryvAuthentication": {
        "apiEndpoint": "https://alice.pryv.me/",
        "accessId": "alices-verification-abc"
      }
    }
  }
}
Authorization: "bobs-token-for-alice alices-token-for-bob"

It should contain both tokens, separated by a whitespace.

GET {apiEndpoint}/access-info

Authorization: alices-token-for-bob
{
  "id": "alices-verification-abc",
  "token": "alices-token-for-bob",
  "type": "shared",
  "name": "alices-access",
  "permissions": [
    {
      "streamId": "verify",
      "level": "read"
    }
  ],
}

Custom Authentication function

You will find the code used by the custom auth step to validate Alice’s identity below:

const https = require("https");
module.exports = function (context, callback) {
  const access = context.access;
  if (
    access.clientData &&
    access.clientData.customAuth &&
    access.clientData.customAuth.PryvAuthentication
  ) {
    https
      .get(
        access.clientData.customAuth.PryvAuthentication.apiEndpoint +
          "/access-info?auth=" +
          context.callerId,
        (res) => {
          if (
            res.headers["pryv-access-id"] ===
            access.clientData.customAuth.PryvAuthentication.accessId
          ) {
            return callback();
          }
          callback(new Error("accessIds do not match"));
        }
      )
      .end();
  } else {
    callback();
  }
};

The arguments context and callback need to be passed as arguments to the method. Available properties of the context can be found in the fields described in the section What is the custom auth step.

module.exports = function(context, callback) {
  // ...
}

The method first verifies that the access has a clientData property containing the access to verify:

if (access.clientData && access.clientData.customAuth && access.clientData.customAuth.PryvAuthentication) {
  // perform authentication step
} else {
  callback();
}

If it does not, the authentication step is skipped.

If such a verification is required, a getAccessInfo API call is done to retrieve the information of Alice’s token and verify if it matches the expected id:

http.get(access.clientData.customAuth.PryvAuthentication.apiEndpoint + '/access-info?auth=' + context.callerId, (res) => {
  //alice accessId == clientData.customAuth.PryvAuthentication.accessId
  const authenticatedAccess = res.body.access;
  if (authenticatedAccess.id == access.clientData.customAuth.PryvAuthentication.accessId) {
    return callback();
  }
  callback(new Error('accessIds do not match'));
});

Custom Auth Step features

You can access NodeJS core modules inside the custom auth function.

As of template version v1.0.35, the Node version is 12.13.1.

Authenticate data access with an external service

In the previous section, we presented a way to perform the authentication step against Pryv.io.
In some cases, you might want to perform the validation step against a third-party API. This will require the validation of an additional token from the chosen external service.

We invite you to contact us directly if you wish to implement such a verification with Pryv.io.