Build a trusted user access service using Azure Functions

This article describes how to use Azure Functions to build a trusted user access service.

Important

The endpoint created at the end of this tutorial isn't secure. Be sure to read about the security details in the Azure Function Security article. You need to add security to the endpoint to ensure bad actors can't provision tokens.

Download Code

Find the finalized code for this quickstart on GitHub

Prerequisites

Overview

Diagram for trusted service architecture

For this tutorial we'll be creating an Azure Function that will serve as a trusted token provisioning service. You can use this tutorial to bootstrap your own token provisioning service.

This service is responsible for authenticating users to Azure Communication Services. Users of your Communication Services applications will require an Access Token in order to participate in chat threads and VoIP calls. The Azure Function will work as a trusted middleman between the user and the Communication Services. This allows you to provision access tokens without exposing your resource connection string to your users.

For more information, see the client-server architecture and authentication and authorization conceptual documentation.

Setting up

Azure Functions set up

Let's first set up the basic structure for our Azure function. Step by step instructions on the set up can be found here: Create a function using Visual Studio Code

Our Azure Function requires the following configuration:

  • Language: JavaScript
  • Template: HTTP Trigger
  • Authorization Level: Anonymous (This can be switched later if you prefer a different authorization model)
  • Function Name: User defined

After following the Azure Functions instructions with the above configuration, you should have a project in Visual Studio Code for the Azure Function with an index.js file that contains the function itself. The code inside of this file should be as follows:


module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    const name = (req.query.name || (req.body && req.body.name));
    const responseMessage = name
        ? "Hello, " + name + ". This HTTP triggered function executed successfully."
        : "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: responseMessage
    };
}

We'll now proceed to install Azure Communication Services libraries.

Install communication services libraries

We'll use the Identity library to generate User Access Tokens.

Use the npm install command to install the Azure Communication Services Identity SDK for JavaScript.


npm install @azure/communication-identity --save

The --save option lists the library as a dependency in your package.json file.

At the top of the index.js file, import the interface for the CommunicationIdentityClient

const { CommunicationIdentityClient } = require('@azure/communication-identity');

Access token generation

To allow our Azure Function to generate User Access Tokens, we'll first need use the connection string for our Communication Services resource.

Visit the resource provisioning quickstart for more information on retrieving your connection string.

const connectionString = 'INSERT YOUR RESOURCE CONNECTION STRING'

Next, we'll modify our original function to generate User Access Tokens.

User Access Tokens are generated by creating a user from the createUser method. Once the user is created we can use the getToken method to generate a token for that user which the Azure Function returns.

For this example, we will configure the token scope to voip. Other scopes might be necessary for your application. Learn more about scopes

module.exports = async function (context, req) {
    let tokenClient = new CommunicationIdentityClient(connectionString);

    const user = await tokenClient.createUser();

    const userToken = await tokenClient.getToken(user, ["voip"]);

    context.res = {
        body: userToken
    };
}

For existing Communication Services CommunicationUser, you can skip the creation step and just generate an access token. More details found in the Create user access tokens quickstart.

Test the Azure Function

Run the Azure Function locally using F5. This will initialize the Azure Function locally and make it accessible through: http://localhost:7071/api/FUNCTION_NAME. Check out additional documentation on running locally

Open the URL on your browser and you should see a response body with the Communication User ID, token and expiration for the token.

Screenshot showing a Response example for the created Azure Function.

Deploy the Function to Azure

To deploy your Azure Function, you can follow step by step instructions

In summary, you will need to:

  1. Sign in to Azure from Visual Studio
  2. Publish your project to your Azure account. Here you will need to choose an existing subscription.
  3. Create a new Azure Function resource using the Visual Studio wizard or use an existing resource. For a new resource, you will need to configure it to your desired region, runtime and unique identifier.
  4. Wait for deployment to finalize
  5. Run the function 🎉

Run Azure Function

Run the Azure function using the url http://<function-appn-ame>.azurewebsites.net/api/<function-name>

You can find the URL by right clicking the function on Visual Studio Code and copying the Function URL.

For more information on running your Azure function

Securing Azure Function

As part of setting up an trusted service to provision access tokens for users, we need to take into account the security of that endpoint to make sure no bad actor can randomly create tokens for your service. Azure Functions provide built-in security features that you can use to secure the endpoint using different types of authentication policies. Read more about Azure Function Security

Clean up resources

If you want to clean up and remove a Communication Services subscription, you can delete the resource or resource group. Deleting the resource group also deletes any other resources associated with it. You can find out more about cleaning up Azure Communication Service resources and cleaning Azure Function Resources.

Next steps

You may also want to: