Consentric

Overview & Set-up

Consentric provides an integration to extend Auth0's universal login to include collection of consent as part of the login flow.

How It Works

The example shows how authenticating with Auth0 can be extended to include a redirect to a page containing a Consentric widget.

The authenticating user can then interact with the widget recording their permissions in a progressive manner.

On submission, the Auth0 authentication flow completes.

API Access

In order to access the Consentric API the Integration will retrieve and store an API access token and store this for the entire Auth0 Tenant.

The API token will be stored in global.consentricApiToken which will be available to other rules running within the Auth0 context.

The expiry date of this token will also be stored in global.consentricApiToken.exp to indicate when the token expires.

User app_metadata

Once enabled for a tenant an entry will be created in the users app_metadata on login

In order to reflect a user's consents for the log in flow a token is generated and stored for a user on log in.

This will be stored in the user's app_metadata under the namespace consentric .

The integration will then pass this value to the associated web page by appending the value to the URL.
i.e. https://yoursite.com/consent-capture?token=5cbf86968b08b7f45e454b39bff35e93

The integration will manage all aspects of this for you but adequate space will be needed in app_metadata to accommodate the token and expiry for the user.

Installation

Pre-requisites

  • An active Auth0 account (the application you are securing with Auth0)
  • A configured Consentric instance with Progressive Consent enabled
  • A self-hosted webpage into which the Progressive Widget can be embedded (
  • Consentric API Client Details (sent to you in your Consentric sign up email)

Setup page with Progressive Widget

The example flow works by redirecting out of Auth0's login flow to a custom webpage containing a Progressive widget.

The custom webpage needs to include the following Javascript snippet to support the Auth0 flow.

N.B. Ensure you populate the config object with relevant properties from your Consentric application and Auth0 tenant.

📘

Config Values

The values of your Consentric application ID, client ID and client secret will be in your welcome emails. Please contact [email protected] if you have any issues.

<script>
  const urlParams = new URLSearchParams(
    window.location.search,
  );  

  const config = {
      elementId: <SELECTOR ID TO BIND THE CONSENTRIC WIDGET TO>,
      templateId: <CONSENTRIC TEMPLATE ID>,
      ruleId: <CONSENTRIC RULE ID>,
      auth0Domain: <ORGANISATION AUTH0 DOMAIN> 
  };

  // e.g.
  // const config = {
  //     elementId: 'mld-prog-widg',
  //     templateId: 'SVxfz4fUbnM',
  //     ruleId: 'jMDMcKcV8Th',
  //     auth0Domain: 'lightningenergy.eu.auth0.com' 
  // };

  const token = urlParams.get('token');
  const auth0State = urlParams.get('state');
  const returnUrl = 'https://' + config.auth0Domain + '/continue?state=' + auth0State;

  const onEmptyLoad = () => {
    console.log('EMPTYLOAD')
    window.location.href = returnUrl;
    //window.location.replace(returnUrl);
  };

  const onSuccess = () => {
    console.log('SUCCESS')
    //window.location.href = returnUrl;
    window.location.replace(returnUrl);
  };

  const events = {
    onSuccess,
    onEmptyLoad
  }

  window.addEventListener('load', function () {
    ProgressiveWidget.load({
      templateId: config.templateId,
      ruleId: config.ruleId,
      id: config.elementId,
      token,
      consentricLogo: true,
      display: {
        location: 'center',
        closeOnSubmit: false,
        displayCancelButtons: false
      },
      events
    });
  });
</script>
<script src="https://scripts.consentric.io/progressive-consent.min.js"></script>

Add Configuration Properties

  1. Navigate to your Auth0 Management Dashboard
  2. Click on the Rules Link from the left hand menu.
  3. Add the Required Properties to the Rule Configuration
    • CONSENTRIC_AUTH_HOST - The URL to authenticate against for your consentric API token. i.e. https://consentric.eu.auth0.com
    • CONSENTRIC_API_HOST - The Consentric API host URL i.e. https://api.consentric.io
    • CONSENTRIC_AUDIENCE - The name of the Consentric API being called i.e. https://api.consentric.io
    • CONSENTRIC_CLIENT_ID - The ClientId issued to you
    • CONSENTRIC_CLIENT_SECRET - The ClientSecret issued to you
    • CONSENTRIC_APPLICATION_ID - The ApplicationId issued to you
    • CONSENTRIC_REDIRECT_URL - The location of the page containing the widget to be included in the Auth0 authentication flow.

Create the Rule

  1. go to Rules > Create Rule and select the MyLife Digital Progressive Consent template
  2. Copy the contents of the rule below into the editor and Click Save
function consentricIntegration(user, context, callback) {
    const axios = require('[email protected]');
    const moment = require('[email protected]');
    const { Auth0RedirectRuleUtilities } = require("@auth0/[email protected]");

    const ruleUtils = new Auth0RedirectRuleUtilities(
        user,
        context,
        configuration
    );

    const asMilliSeconds = (seconds) => seconds * 1000;

    const {
        CONSENTRIC_AUTH_HOST,
        CONSENTRIC_API_HOST,
        CONSENTRIC_AUDIENCE,
        CONSENTRIC_CLIENT_ID,
        CONSENTRIC_CLIENT_SECRET,
        CONSENTRIC_APPLICATION_ID,
        CONSENTRIC_REDIRECT_URL
    } = configuration;

    const consentricAuth = axios.create({
        baseURL: CONSENTRIC_AUTH_HOST,
        timeout: 1000,
    });

    const consentricApi = axios.create({
        baseURL: CONSENTRIC_API_HOST,
        timeout: 1000,
    });

    // Returns Consentric API Access Token (JWT) from either the global cache or generates it anew from clientId and secret
    const getConsentricApiAccessToken = async () => {
        const consentricApiTokenNotValid = (!global.consentricApiToken) ||
            global.consentricApiToken.exp < new Date().getTime();

        if (consentricApiTokenNotValid) {
            try {
                // Exchange Credentials for Consentric Api Access token
                const { data: { expires_in, access_token } } = await consentricAuth                
                    .post('/oauth/token', {
                        grant_type: 'client_credentials',
                        client_id: CONSENTRIC_CLIENT_ID,
                        client_secret: CONSENTRIC_CLIENT_SECRET,
                        audience: CONSENTRIC_AUDIENCE,
                        applicationId: CONSENTRIC_APPLICATION_ID,
                    });
                
                

                const expiryInMs = new Date().getTime() + asMilliSeconds(expires_in);
                const auth = {
                    jwt: access_token,
                    exp: expiryInMs
                };

                // Persist API Access token in global properties
                global.consentricApiToken = auth;

            } catch (error) {
                console.error('Unable to retrieve API Access token for Consentric. Please check that your credentials (CONSENTRIC_CLIENT_ID and CONSENTRIC_CLIENT_SECRET) are correct.');
                throw error;
            }
        }

        return global.consentricApiToken;
    };

    // Creates Citizen Record in Consentric with Auth0 Id
    const createCitizen = ({ userRef, apiAccessToken }) => {
        console.log(`Upserting Consentric Citizen record for ${userRef}`);
        const data = {
            applicationId: CONSENTRIC_APPLICATION_ID,
            externalRef: userRef,
        };

        return consentricApi
            .post('/v1/citizens', data, {
                headers: {
                    Authorization: 'Bearer ' + apiAccessToken
                },
            })
            .catch(err => {
                if (err.response.status !== 409) { // 409 indicates Citizen with given reference already exists in Consentric
                    console.error(err);
                    throw err;
                }
            });
    };

    // Function to retrieve Consentric User Token from User Metadata
    const getConsentricUserTokenFromMetadata = user => user.app_metadata && user.app_metadata.consentric;

    // Generates On Demand Consentric User Token for the given User using the API Access Token
    const generateConsentricUserAccessToken = async ({ userRef, apiAccessToken }) => {
        try {
            console.log(`Attempting to generate access token API for ${userRef}`);

            const { data: { token, expiryDate: exp } } = await consentricApi
                .post('/v1/access-tokens/tokens',
                    {
                        applicationId: CONSENTRIC_APPLICATION_ID,
                        externalRef: userRef,
                        expiryDate: moment().add(3, 'months').toISOString()
                    },
                    {
                        headers: {
                            Authorization: 'Bearer ' + apiAccessToken
                        }
                    }
                );

            return {
                token,
                exp
            };

        } catch (err) {
            console.error(err);
            throw err;
        }
    };

    const loadConsentricUserAccessToken = async ({ user }) => {
        try {
            const metadataUserToken = getConsentricUserTokenFromMetadata(user);            
            if ((metadataUserToken) && moment(metadataUserToken.exp).subtract(1, "days").isAfter(moment())) return metadataUserToken;
        
            const { jwt: apiAccessToken } = await getConsentricApiAccessToken();            
            const apiCredentials = {
                userRef: user.user_id,
                apiAccessToken,
            };

            // Create Citizen with Auth0 UserId
            await createCitizen(apiCredentials);

            // Generate an On Demand Access Token for the created citizen
            const generatedToken = await generateConsentricUserAccessToken(apiCredentials);

            // Persist the app_metadata update            
            await auth0.users.updateAppMetadata(user.user_id, { consentric: generatedToken });

            return generatedToken;
        } catch (err) {
            console.error(`Issue Loading Consentric User Access Token for user ${user.user_id} - ${err}`);
            throw err;
        }
    };

    const initConsentricFlow = async () => {
        try {
            const { token } = await loadConsentricUserAccessToken({ user });
            const urlConnector = CONSENTRIC_REDIRECT_URL.includes('?') ? '&' : '?';
            const redirectUrl = CONSENTRIC_REDIRECT_URL + urlConnector + 'token=' + token;
    
            context.redirect = {
                url: redirectUrl
            };
            
        } catch (err) {
            console.error(`CONSENTRIC RULE ABORTED: ${err}`);
        }
        return callback(null, user, context);
    };

    if (ruleUtils.canRedirect) {
        return initConsentricFlow();
    } else {
        // Run after Redirect or Silent Auth
        return callback(null, user, context);
    }
}

🚧

Please Note

Once marked as active, all logins for your tenant will redirect users based on the configuration specified above. Please make sure all components have been configured correctly and verified before activating the integration.

Once you are happy with your configuration Mark the rule as Active

Updated 8 months ago


Overview & Set-up


Consentric provides an integration to extend Auth0's universal login to include collection of consent as part of the login flow.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.