Quickstart: Create and manage access tokens

Access tokens let ACS SDKs authenticate directly against Azure Communication Services as a particular identity. You'll need to create some if you want your users to join a call or chat thread within your application.

You can also use the ACS SDKs to create identities and manage your access tokens and in this quickstart we'll be learning how to do this. For production use cases we recommend generating access tokens on a server-side service.

Any prices seen in images throughout this tutorial are for demonstration purposes only.

Prerequisites

Final Code

Find the finalized code for this quickstart on GitHub.

Setting Up

Create a new C# application

In a console window (such as cmd, PowerShell, or Bash), use the dotnet new command to create a new console app with the name AccessTokensQuickstart. This command creates a simple "Hello World" C# project with a single source file: Program.cs.

dotnet new console -o AccessTokensQuickstart

Change your directory to the newly created app folder and use the dotnet build command to compile your application.

cd AccessTokensQuickstart
dotnet build

You should see a simple "Hello World" output. If everything works, it means that your setup is working correctly and that we can get started writing our ACS specific code.

Install the package

While still in the application directory, install the Azure Communication Services Identity library for .NET package by using the dotnet add package command.

dotnet add package Azure.Communication.Identity --version 1.0.0

Set up the app framework

From the project directory:

  1. Open Program.cs file in a text editor
  2. Add a using directive to include the Azure.Communication.Identity namespace
  3. Update the Main method declaration to support async code

Use the following code to begin:

using System;
using Azure;
using Azure.Core;
using Azure.Communication.Identity;

namespace AccessTokensQuickstart
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            Console.WriteLine("Azure Communication Services - Access Tokens Quickstart");

            // Quickstart code goes here
        }
    }
}

Authenticate the client

Now we'll initialize a CommunicationIdentityClient with your connection string. The code below retrieves the connection string for the resource from an environment variable named COMMUNICATION_SERVICES_CONNECTION_STRING. Learn how to manage your resource's connection string.

Add the following code to the Main method:

// This code demonstrates how to fetch your connection string
// from an environment variable.
string connectionString = Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_CONNECTION_STRING");
var client = new CommunicationIdentityClient(connectionString);

Alternatively, you can separate endpoint and access key.

// This code demonstrates how to fetch your endpoint and access key
// from an environment variable.
string endpoint = Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_ENDPOINT");
string accessKey = Environment.GetEnvironmentVariable("COMMUNICATION_SERVICES_ACCESSKEY");
var client = new CommunicationIdentityClient(new Uri(endpoint), new AzureKeyCredential(accessKey));

If you have an Azure Active Directory(AD) application set up, see Use Service Principals, you may also authenticate with AD.

TokenCredential tokenCredential = new DefaultAzureCredential();
var client = new CommunicationIdentityClient(new Uri(endpoint), tokenCredential);

Create an identity

To create access tokens, you'll need an identity. Azure Communication Services maintains a lightweight identity directory for this purpose. Use the createUser method to create a new entry in the directory with a unique Id. The identity is required later to issue access tokens.

var identityResponse = await client.CreateUserAsync();
var identity = identityResponse.Value;
Console.WriteLine($"\nCreated an identity with ID: {identity.Id}");

You should store the received identity with a mapping to your application's users. For example, by storing them in your application server's database.

Issue identity access tokens

Once you have an identity, use the GetToken method to issue an access token for the identity. The scopes parameter defines set of permissions/abilities, that this access token can perform. See the list of supported actions. A new instance of a communicationUser can also be constructed based on string representation of an Azure Communication Service identity.

// Issue an access token with the "voip" scope for an identity
var tokenResponse = await client.GetTokenAsync(identity, scopes: new [] { CommunicationTokenScope.VoIP });

// Get the token from the response
var token =  tokenResponse.Value.Token;
var expiresOn = tokenResponse.Value.ExpiresOn;

// Write the token details to the screen
Console.WriteLine($"\nIssued an access token with 'voip' scope that expires at {expiresOn}:");
Console.WriteLine(token);

Access tokens are short-lived credentials that need to be reissued. Not doing so might cause disruption of your application's users experience. The expiresOn response property indicates the lifetime of the access token.

Create an identity and issue an access token within the same request

You can use the CreateUserAndTokenAsync method to create a Communication Services identity and issue an access token for it at the same time. The scopes parameter defines set of permissions/abilities, that this access token can perform. See the list of supported actions.

// Issue an identity and an access token with the "voip" scope for the new identity
var identityAndTokenResponse = await client.CreateUserAndTokenAsync(scopes: new[] { CommunicationTokenScope.VoIP });

// Retrieve the identity, token and expiry date from the response
var identity = identityAndTokenResponse.Value.User;
var token = identityAndTokenResponse.Value.AccessToken.Token;
var expiresOn = identityAndTokenResponse.Value.AccessToken.ExpiresOn;

// Print these details to the screen
Console.WriteLine($"\nCreated an identity with ID: {identity.Id}");
Console.WriteLine($"\nIssued an access token with 'voip' scope that expires at {expiresOn}:");
Console.WriteLine(token);

Refresh an access token

To refresh an access token, pass an instance of the CommunicationUserIdentifier object into GetTokenAsync. If you've stored this Id and need to create a new CommunicationUserIdentifier, you can do so by passing your stored Id into the CommunicationUserIdentifier constructor as follows:

var identityToRefresh = new CommunicationUserIdentifier(identity.Id);
var tokenResponse = await client.GetTokenAsync(identityToRefresh, scopes: new [] { CommunicationTokenScope.VoIP });

Revoke access tokens

In some cases, you may need to explicitly revoke access tokens. For example, when an application's user changes the password they use to authenticate to your service. The RevokeTokensAsync method invalidates all active access tokens, that were issued to the identity.

await client.RevokeTokensAsync(identity);
Console.WriteLine($"\nSuccessfully revoked all access tokens for identity with ID: {identity.Id}");

Delete an identity

Deleting an identity revokes all active access tokens and prevents you from issuing access tokens for the identities. It also removes all the persisted content associated with the identity.

await client.DeleteUserAsync(identity);
Console.WriteLine($"\nDeleted the identity with ID: {identity.Id}");

Run the code

Once complete you can run the application from your application directory with the dotnet run command.

dotnet run

Prerequisites

Final Code

Find the finalized code for this quickstart on GitHub.

Setting Up

Create a new Node.js Application

Open your terminal or command window create a new directory for your app, and navigate to it.

mkdir access-tokens-quickstart && cd access-tokens-quickstart

Run npm init -y to create a package.json file with default settings.

npm init -y

Install the package

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.

Set up the app framework

Within the project directory, use the following code to begin:

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

const main = async () => {
  console.log("Azure Communication Services - Access Tokens Quickstart")

  // Quickstart code goes here
};

main().catch((error) => {
  console.log("Encountered an error");
  console.log(error);
})

Once complete, save the new file as issue-access-token.js in the project directory.

Authenticate the client

Instantiate a CommunicationIdentityClient with your connection string. The code below retrieves the connection string for the resource from an environment variable named COMMUNICATION_SERVICES_CONNECTION_STRING. Learn how to manage your resource's connection string.

Add the following code to the main method:

// This code demonstrates how to fetch your connection string
// from an environment variable.
const connectionString = process.env['COMMUNICATION_SERVICES_CONNECTION_STRING'];

// Instantiate the identity client
const identityClient = new CommunicationIdentityClient(connectionString);

Alternatively, you can separate the endpoint and access key.

// This code demonstrates how to fetch your endpoint and access key
// from an environment variable.
const endpoint = process.env["COMMUNICATION_SERVICES_ENDPOINT"];
const accessKey = process.env["COMMUNICATION_SERVICES_ACCESSKEY"];

// Create the credential
const tokenCredential = new AzureKeyCredential(accessKey);

// Instantiate the identity client
const identityClient = new CommunicationIdentityClient(endpoint, tokenCredential)

If you have an Azure Active Directory(Azure AD) Application setup, see Use service principals, you may also authenticate with Azure AD.

const endpoint = process.env["COMMUNICATION_SERVICES_ENDPOINT"];
const tokenCredential = new DefaultAzureCredential();
const identityClient = new CommunicationIdentityClient(endpoint, tokenCredential);

Create an identity

To create access tokens, you'll need an identity. Azure Communication Services maintains a lightweight identity directory. Use the createUser method to create a new entry in the directory with a unique Id. The created identity is required later to issue access tokens.

let identityResponse = await identityClient.createUser();
console.log(`\nCreated an identity with ID: ${identityResponse.communicationUserId}`);

You should store received identities with a mapping to your application's users. For example, in your application server's database.

Issue access tokens

Use the getToken method to issue an access token for an already existing Communication Services identity. The scopes parameter defines a list of permissions/roles, that this token can perform/use. See the list of supported actions. A new instance of parameter communicationUser can be constructed based on string representation of an Azure Communication Service identity.

// Issue an access token with the "voip" scope for an identity
let tokenResponse = await identityClient.getToken(identityResponse, ["voip"]);

// retrieve the token and its expiry date from the response
const { token, expiresOn } = tokenResponse;

// Print the expiry date and token to the screen
console.log(`\nIssued an access token with 'voip' scope that expires at ${expiresOn}:`);
console.log(token);

Access tokens are short-lived credentials that need to be reissued. Not doing so might cause disruption of your application's users experience. The expiresOn property indicates the lifetime of the access token.

Create an identity and issue an access token within one method call

You can use the createUserAndToken method to create a Communication Services identity and issue an access token for it in one go. The scopes parameter, is the same as above. We'll once again just create one with the voip scope.

// Issue an identity and an access token with the "voip" scope for the new identity
let identityTokenResponse = await identityClient.createUserAndToken(["voip"]);

// retrieve the token, its expiry date and user from the response
const { token, expiresOn, user } = identityTokenResponse;

// print these details to the screen
console.log(`\nCreated an identity with ID: ${user.communicationUserId}`);
console.log(`\nIssued an access token with 'voip' scope that expires at ${expiresOn}:`);
console.log(token);

Refresh access tokens

As tokens expire, you'll periodically need to refresh them. Refreshing is easy just call getToken again with the same identity that was used to issue the tokens. You'll also need to provide the scopes of the refreshed tokens.

// Value of identityResponse represents the Azure Communication Services identity stored during identity creation and then used to issue the tokens being refreshed
let refreshedTokenResponse = await identityClient.getToken(identityResponse, ["voip"]);

Revoke access tokens

In some cases, you may want to revoke access tokens. For example, when an application's user changes the password they use to authenticate to your service. The revokeTokens method invalidates all active access tokens, that were issued to the identity.

await identityClient.revokeTokens(identityResponse);

console.log(`\nSuccessfully revoked all access tokens for identity with ID: ${identityResponse.communicationUserId}`);

Delete an identity

Deleting an identity revokes all active access tokens and prevents you from issuing access tokens for the identity. It also removes all the persisted content associated with the identity.

await identityClient.deleteUser(identityResponse);

console.log(`\nDeleted the identity with ID: ${identityResponse.communicationUserId}`);

Run the code

From a console prompt, navigate to the directory containing the issue-access-token.js file, then execute the following node command to run the app.

node ./issue-access-token.js

Prerequisites

Final Code

Find the finalized code for this quickstart on GitHub.

Setting Up

Create a new Python application

  1. Open your terminal or command window create a new directory for your app, and navigate to it.

    mkdir access-tokens-quickstart && cd access-tokens-quickstart
    
  2. Use a text editor to create a file called issue-access-tokens.py in the project root directory and add the structure for the program, including basic exception handling. You'll add all the source code for this quickstart to this file in the following sections.

    import os
    from azure.communication.identity import CommunicationIdentityClient, CommunicationUserIdentifier
    
    try:
       print("Azure Communication Services - Access Tokens Quickstart")
       # Quickstart code goes here
    except Exception as ex:
       print("Exception:")
       print(ex)
    

Install the package

While still in the application directory, install the Azure Communication Services Identity SDK for Python package by using the pip install command.

pip install azure-communication-identity

Authenticate the client

Next we'll instantiate a CommunicationIdentityClient with your connection string. The code below retrieves the connection string for the resource from an environment variable named COMMUNICATION_SERVICES_CONNECTION_STRING. Learn how to manage your resource's connection string.

Add this code inside the try block:

# This code demonstrates how to fetch your connection string
# from an environment variable.
connection_string = os.environ["COMMUNICATION_SERVICES_CONNECTION_STRING"]

# Instantiate the identity client
client = CommunicationIdentityClient.from_connection_string(connection_string)

Alternatively, if you have an Azure Active Directory(Azure AD) application set up, see Use service principals, you may also authenticate with Azure AD.

endpoint = os.environ["COMMUNICATION_SERVICES_ENDPOINT"]
client = CommunicationIdentityClient(endpoint, DefaultAzureCredential())

Create an identity

To create access tokens, you'll need an identity. Azure Communication Services maintains a lightweight identity directory. Use the create_user method to create a new entry in the directory with a unique Id. The identity is required later to issue access tokens.

identity = client.create_user()
print("\nCreated an identity with ID: " + identity.properties['id'])

You should store the received identity with a mapping to your application's users. For example, by storing them in your application server's database.

Issue access tokens

Use the get_token method to issue an access token for already existing Communication Services identity. The scopes parameter defines set of permissions/abilities, that this access token can perform. See the list of supported actions. a new instance of parameter CommunicationUserIdentifier can also be constructed based on string representation of Azure Communication Service identity.

# Issue an access token with the "voip" scope for an identity
token_result = client.get_token(identity, ["voip"])
expires_on = token_result.expires_on.strftime("%d/%m/%y %I:%M %S %p")

# Print these details to the screen
print("\nIssued an access token with 'voip' scope that expires at " + expires_on + ":")
print(token_result.token)

Access tokens are short-lived credentials that need to be reissued. Not doing so might cause disruption of your application's users experience. The expires_on response property indicates the lifetime of the access token.

Create an identity and issue an access token within the same request

You can use the create_user_and_token method to create a Communication Services identity and issue an access token for it. The scopes parameter defines set of permissions/abilities, that this access token can perform.. See the list of supported actions.

# Issue an identity and an access token with the "voip" scope for the new identity
identity_token_result = client.create_user_and_token(["voip"])

# Get the token details from the response
identity = identity_token_result[0]
token = identity_token_result[1].token
expires_on = identity_token_result[1].expires_on.strftime("%d/%m/%y %I:%M %S %p")

# Print these to the screen
print("\nCreated an identity with ID: " + identity.properties['id'])
print("\nIssued an access token with 'voip' scope that expires at " + expires_on + ":")
print(token)

Refresh access tokens

To refresh an access token, use the CommunicationUserIdentifier object to reissue a token by passing in the existing identity:

# The existingIdentity value represents identity of Azure Communication Services stored during identity creation
identity = CommunicationUserIdentifier(existingIdentity)
token_result = client.get_token(identity, ["voip"])

Revoke access tokens

In some cases, you may want to explicitly revoke access tokens. For example, when an application's user changes the password they use to authenticate to your service. The revoke_tokens method invalidates all active access tokens, that were issued to the identity.

client.revoke_tokens(identity)
print("\nSuccessfully revoked all access tokens for identity with ID: " + identity.properties['id'])

Delete an identity

Deleting an identity revokes all active access tokens and prevents you from issuing access tokens for the identity. It also removes all the persisted content associated with the identity.

client.delete_user(identity)
print("\nDeleted the identity with ID: " + identity.properties['id'])

Run the code

From a console prompt, navigate to the directory containing the issue-access-tokens.py file, then execute the following python command to run the app.

python ./issue-access-tokens.py

Prerequisites

Final Code

Find the finalized code for this quickstart on GitHub.

Setting Up

Create a new Java application

Open your terminal or command window. Navigate to the directory where you'd like to create your Java application. Run the command below to generate the Java project from the maven-archetype-quickstart template.

mvn archetype:generate -DgroupId=com.communication.quickstart -DartifactId=communication-quickstart -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

You'll notice that the 'generate' task created a directory with the same name as the artifactId. Under this directory, the src/main/java directory contains the project source code, the src/test/java directory contains the test source, and the pom.xml file is the project's Project Object Model, or POM. This file is used for project configuration parameters.

Install the ACS packages

Open the pom.xml file in your text editor. Add the following dependency element to the group of dependencies.

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-communication-identity</artifactId>
    <version>1.0.0</version>
</dependency>

This will instruct Maven to install the ACS Identity SDK when we use it later on.

Set up the app framework

From the project directory:

  1. Navigate to the /src/main/java/com/communication/quickstart directory
  2. Open the App.java file in your editor
  3. Replace the System.out.println("Hello world!"); statement
  4. Add import directives

Use the following code to begin:

package com.communication.quickstart;

import com.azure.communication.common.*;
import com.azure.communication.identity.*;
import com.azure.communication.identity.models.*;
import com.azure.core.credential.*;

import java.io.IOException;
import java.time.*;
import java.util.*;

public class App
{
    public static void main( String[] args ) throws IOException
    {
        System.out.println("Azure Communication Services - Access Tokens Quickstart");
        // Quickstart code goes here
    }
}

Authenticate the client

Instantiate a CommunicationIdentityClient with your resource's access key and endpoint. Learn how to manage your resource's connection string. In addition, you can initialize the client with any custom HTTP client that implements the com.azure.core.http.HttpClient interface.

Add the following code to the main method inside App.java:

// You can find your endpoint and access key from your resource in the Azure portal
String endpoint = "https://<RESOURCE_NAME>.communication.azure.com";
String accessKey = "SECRET";

CommunicationIdentityClient communicationIdentityClient = new CommunicationIdentityClientBuilder()
        .endpoint(endpoint)
        .credential(new AzureKeyCredential(accessKey))
        .buildClient();

You can also provide the entire connection string using the connectionString() method instead of providing the endpoint and access key.

// Your can find your connection string from your ACS resource in the Azure portal
String connectionString = "<connection_string>";

CommunicationIdentityClient communicationIdentityClient = new CommunicationIdentityClientBuilder()
    .connectionString(connectionString)
    .buildClient();

If you have an Azure Active Directory(Azure AD) application set up, see Use service principals, you may also authenticate with Azure AD.

String endpoint = "https://<RESOURCE_NAME>.communication.azure.com";
TokenCredential credential = new DefaultAzureCredentialBuilder().build();

CommunicationIdentityClient communicationIdentityClient = new CommunicationIdentityClientBuilder()
        .endpoint(endpoint)
        .credential(credential)
        .buildClient();

Create an identity

To create access tokens, you'll need an identity. Azure Communication Services maintains a lightweight identity directory. Use the createUser method to create a new entry in the directory with a unique Id.

CommunicationUserIdentifier user = communicationIdentityClient.createUser();
System.out.println("\nCreated an identity with ID: " + user.getId());

The created identity is required later to issue access tokens. You should therefore store any received identities with a mapping to your application's user. For example, by storing them in your application server's database.

Issue access tokens

Use the getToken method to issue an access token for already existing Communication Services identity. The scopes parameter defines set of permissions and abilities that this token will be able to perform. See the list of supported actions for valid values. In this case we'll use our user variable created in the previous step to get a token.

// Issue an access token with the "voip" scope for a user identity
List<CommunicationTokenScope> scopes = new ArrayList<>(Arrays.asList(CommunicationTokenScope.VOIP));
AccessToken accessToken = communicationIdentityClient.getToken(user, scopes);
OffsetDateTime expiresAt = accessToken.getExpiresAt();
String token = accessToken.getToken();
System.out.println("\nIssued an access token with 'voip' scope that expires at: " + expiresAt + ": " + token);

Create an identity and issue token in one request

Alternatively, we can use the 'createUserAndToken' method to to create a new entry in the directory with a unique Id and issue an access token.

List<CommunicationTokenScope> scopes = Arrays.asList(CommunicationTokenScope.CHAT);
CommunicationUserIdentifierAndToken result = communicationIdentityClient.createUserAndToken(scopes);
CommunicationUserIdentifier user = result.getUser();
System.out.println("\nCreated a user identity with ID: " + user.getId());
AccessToken accessToken = result.getUserToken();
OffsetDateTime expiresAt = accessToken.getExpiresAt();
String token = accessToken.getToken();
System.out.println("\nIssued an access token with 'chat' scope that expires at: " + expiresAt + ": " + token);

Access tokens are short-lived credentials that need to be reissued. Not doing so might cause disruption of your application's users experience. The expiresAt property indicates the lifetime of the access token.

Refresh access tokens

To refresh an access token, use the CommunicationUserIdentifier object to reissue:

// existingIdentity represents identity of Azure Communication Services stored during identity creation
CommunicationUserIdentifier identity = new CommunicationUserIdentifier(existingIdentity.getId());
AccessToken response = communicationIdentityClient.getToken(identity, scopes);

Revoke an access token

In some cases, you may explicitly revoke access tokens. For example, when an application's user changes the password they use to authenticate to your service. The revokeTokens method invalidates all active access tokens for a particular user. In this case we'll again use the previously created user.

communicationIdentityClient.revokeTokens(user);
System.out.println("\nSuccessfully revoked all access tokens for user identity with ID: " + user.getId());

Delete an identity

Deleting an identity revokes all active access tokens and prevents you from issuing access tokens for the identity. It also removes all the persisted content associated with the identity.

communicationIdentityClient.deleteUser(user);
System.out.println("\nDeleted the user identity with ID: " + user.getId());

Run the code

Navigate to the directory containing the pom.xml file and compile the project by using the following mvn command.

mvn compile

Then, build the package.

mvn package

Run the following mvn command to execute the app.

mvn exec:java -Dexec.mainClass="com.communication.quickstart.App" -Dexec.cleanupDaemonThreads=false

The output of the app describes each action that is completed:

Azure Communication Services - Access Tokens Quickstart

Created an identity with ID: 8:acs:4ccc92c8-9815-4422-bddc-ceea181dc774_00000006-19e0-2727-80f5-8b3a0d003502

Issued an access token with 'voip' scope that expires at 30/03/21 08:09 09 AM:
<token signature here>

Created an identity with ID: 8:acs:4ccc92c8-9815-4422-bddc-ceea181dc774_00000006-1ce9-31b4-54b7-a43a0d006a52

Issued an access token with 'voip' scope that expires at 30/03/21 08:09 09 AM:
<token signature here>

Successfully revoked all access tokens for identity with ID: 8:acs:4ccc92c8-9815-4422-bddc-ceea181dc774_00000006-19e0-2727-80f5-8b3a0d003502

Deleted the identity with ID: 8:acs:4ccc92c8-9815-4422-bddc-ceea181dc774_00000006-19e0-2727-80f5-8b3a0d003502

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. Learn more about cleaning up resources.

Next Steps

In this quickstart, you learned how to:

  • Manage identities
  • Issue access tokens
  • Use the Communication Services Identity SDK

You may also want to: