GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-communication-common-java

Azure Communication Services common utilities for Java. Use when working with CommunicationTokenCredential, user identifiers, token refresh, or shared authentication across ACS services.

Ciza · 0 points · 17 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download microsoft-skills-.github_plugins_azure-sdk-java_skills_azure-communication-common-java-e58528d.zip · 6 KB
Part of microsoft/skills — 195 skills

Install

skills CLI npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-java/skills/azure-communication-common-java
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git git clone https://github.com/microsoft/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Azure Communication Common (Java)

Shared authentication utilities and data structures for Azure Communication Services.

Installation

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-communication-common</artifactId>
    <version>1.4.0</version>
</dependency>

Key Concepts

Class Purpose
CommunicationTokenCredential Authenticate users with ACS services
CommunicationTokenRefreshOptions Configure automatic token refresh
CommunicationUserIdentifier Identify ACS users
PhoneNumberIdentifier Identify PSTN phone numbers
MicrosoftTeamsUserIdentifier Identify Teams users
UnknownIdentifier Generic identifier for unknown types

CommunicationTokenCredential

Static Token (Short-lived Clients)

import com.azure.communication.common.CommunicationTokenCredential;

// Simple static token - no refresh
String userToken = "<user-access-token>";
CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);

// Use with Chat, Calling, etc.
ChatClient chatClient = new ChatClientBuilder()
    .endpoint("https://<resource>.communication.azure.com")
    .credential(credential)
    .buildClient();

Proactive Token Refresh (Long-lived Clients)

import com.azure.communication.common.CommunicationTokenRefreshOptions;
import java.util.concurrent.Callable;

// Token refresher callback - called when token is about to expire
Callable<String> tokenRefresher = () -> {
    // Call your server to get a fresh token
    return fetchNewTokenFromServer();
};

// With proactive refresh
CommunicationTokenRefreshOptions refreshOptions = new CommunicationTokenRefreshOptions(tokenRefresher)
    .setRefreshProactively(true)      // Refresh before expiry
    .setInitialToken(currentToken);    // Optional initial token

CommunicationTokenCredential credential = new CommunicationTokenCredential(refreshOptions);

Async Token Refresh

import java.util.concurrent.CompletableFuture;

// Async token fetcher
Callable<String> asyncRefresher = () -> {
    CompletableFuture<String> future = fetchTokenAsync();
    return future.get();  // Block until token is available
};

CommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(asyncRefresher)
    .setRefreshProactively(true);

CommunicationTokenCredential credential = new CommunicationTokenCredential(options);

Entra ID (Azure AD) Authentication

import com.azure.identity.InteractiveBrowserCredentialBuilder;
import com.azure.communication.common.EntraCommunicationTokenCredentialOptions;
import java.util.Arrays;
import java.util.List;

// For Teams Phone Extensibility
InteractiveBrowserCredential entraCredential = new InteractiveBrowserCredentialBuilder()
    .clientId("<your-client-id>")
    .tenantId("<your-tenant-id>")
    .redirectUrl("<your-redirect-uri>")
    .build();

String resourceEndpoint = "https://<resource>.communication.azure.com";
List<String> scopes = Arrays.asList(
    "https://auth.msft.communication.azure.com/TeamsExtension.ManageCalls"
);

EntraCommunicationTokenCredentialOptions entraOptions = 
    new EntraCommunicationTokenCredentialOptions(entraCredential, resourceEndpoint)
        .setScopes(scopes);

CommunicationTokenCredential credential = new CommunicationTokenCredential(entraOptions);

Communication Identifiers

CommunicationUserIdentifier

import com.azure.communication.common.CommunicationUserIdentifier;

// Create identifier for ACS user
CommunicationUserIdentifier user = new CommunicationUserIdentifier("8:acs:resource-id_user-id");

// Get raw ID
String rawId = user.getId();

PhoneNumberIdentifier

import com.azure.communication.common.PhoneNumberIdentifier;

// E.164 format phone number
PhoneNumberIdentifier phone = new PhoneNumberIdentifier("+14255551234");

String phoneNumber = phone.getPhoneNumber();  // "+14255551234"
String rawId = phone.getRawId();              // "4:+14255551234"

MicrosoftTeamsUserIdentifier

import com.azure.communication.common.MicrosoftTeamsUserIdentifier;

// Teams user identifier
MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier("<teams-user-id>")
    .setCloudEnvironment(CommunicationCloudEnvironment.PUBLIC);

// For anonymous Teams users
MicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier("<teams-user-id>")
    .setAnonymous(true);

UnknownIdentifier

import com.azure.communication.common.UnknownIdentifier;

// For identifiers of unknown type
UnknownIdentifier unknown = new UnknownIdentifier("some-raw-id");

Identifier Parsing

import com.azure.communication.common.CommunicationIdentifier;
import com.azure.communication.common.CommunicationIdentifierModel;

// Parse raw ID to appropriate type
public CommunicationIdentifier parseIdentifier(String rawId) {
    if (rawId.startsWith("8:acs:")) {
        return new CommunicationUserIdentifier(rawId);
    } else if (rawId.startsWith("4:")) {
        String phone = rawId.substring(2);
        return new PhoneNumberIdentifier(phone);
    } else if (rawId.startsWith("8:orgid:")) {
        String teamsId = rawId.substring(8);
        return new MicrosoftTeamsUserIdentifier(teamsId);
    } else {
        return new UnknownIdentifier(rawId);
    }
}

Type Checking Identifiers

import com.azure.communication.common.CommunicationIdentifier;

public void processIdentifier(CommunicationIdentifier identifier) {
    if (identifier instanceof CommunicationUserIdentifier) {
        CommunicationUserIdentifier user = (CommunicationUserIdentifier) identifier;
        System.out.println("ACS User: " + user.getId());
        
    } else if (identifier instanceof PhoneNumberIdentifier) {
        PhoneNumberIdentifier phone = (PhoneNumberIdentifier) identifier;
        System.out.println("Phone: " + phone.getPhoneNumber());
        
    } else if (identifier instanceof MicrosoftTeamsUserIdentifier) {
        MicrosoftTeamsUserIdentifier teams = (MicrosoftTeamsUserIdentifier) identifier;
        System.out.println("Teams User: " + teams.getUserId());
        System.out.println("Anonymous: " + teams.isAnonymous());
        
    } else if (identifier instanceof UnknownIdentifier) {
        UnknownIdentifier unknown = (UnknownIdentifier) identifier;
        System.out.println("Unknown: " + unknown.getId());
    }
}

Token Access

import com.azure.core.credential.AccessToken;

// Get current token (for debugging/logging - don't expose!)
CommunicationTokenCredential credential = new CommunicationTokenCredential(token);

// Sync access
AccessToken accessToken = credential.getToken();
System.out.println("Token expires: " + accessToken.getExpiresAt());

// Async access
credential.getTokenAsync()
    .subscribe(token -> {
        System.out.println("Token: " + token.getToken().substring(0, 20) + "...");
        System.out.println("Expires: " + token.getExpiresAt());
    });

Dispose Credential

// Clean up when done
credential.close();

// Or use try-with-resources
try (CommunicationTokenCredential cred = new CommunicationTokenCredential(options)) {
    // Use credential
    chatClient.doSomething();
}

Cloud Environments

import com.azure.communication.common.CommunicationCloudEnvironment;

// Available environments
CommunicationCloudEnvironment publicCloud = CommunicationCloudEnvironment.PUBLIC;
CommunicationCloudEnvironment govCloud = CommunicationCloudEnvironment.GCCH;
CommunicationCloudEnvironment dodCloud = CommunicationCloudEnvironment.DOD;

// Set on Teams identifier
MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier("<user-id>")
    .setCloudEnvironment(CommunicationCloudEnvironment.GCCH);

Environment Variables

AZURE_COMMUNICATION_ENDPOINT=https://<resource>.communication.azure.com
AZURE_COMMUNICATION_USER_TOKEN=<user-access-token>

Best Practices

  1. Proactive Refresh - Always use setRefreshProactively(true) for long-lived clients
  2. Token Security - Never log or expose full tokens
  3. Close Credentials - Dispose of credentials when no longer needed
  4. Error Handling - Handle token refresh failures gracefully
  5. Identifier Types - Use specific identifier types, not raw strings

Common Usage Patterns

// Pattern: Create credential for Chat/Calling client
public ChatClient createChatClient(String token, String endpoint) {
    CommunicationTokenRefreshOptions refreshOptions = 
        new CommunicationTokenRefreshOptions(this::refreshToken)
            .setRefreshProactively(true)
            .setInitialToken(token);
    
    CommunicationTokenCredential credential = 
        new CommunicationTokenCredential(refreshOptions);
    
    return new ChatClientBuilder()
        .endpoint(endpoint)
        .credential(credential)
        .buildClient();
}

private String refreshToken() {
    // Call your token endpoint
    return tokenService.getNewToken();
}

Trigger Phrases

  • "ACS authentication", "communication token credential"
  • "user access token", "token refresh"
  • "CommunicationUserIdentifier", "PhoneNumberIdentifier"
  • "Azure Communication Services authentication"
Files (skills)
  • references
    • examples.md 14.3 KB
      # Azure Communication Common Java SDK - Examples
      
      Comprehensive code examples for the Azure Communication Services Common SDK for Java.
      
      ## Table of Contents
      - [Maven Dependency](#maven-dependency)
      - [Communication Token Credential](#communication-token-credential)
      - [Communication Identifiers](#communication-identifiers)
      - [Token Refresh Patterns](#token-refresh-patterns)
      - [Entra ID Authentication](#entra-id-authentication)
      - [Complete Application Example](#complete-application-example)
      
      ## Maven Dependency
      
      ```xml
      <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-communication-common</artifactId>
          <version>1.4.0</version>
      </dependency>
      ```
      
      ## Communication Token Credential
      
      ### Static Token (Short-lived Clients)
      
      ```java
      import com.azure.communication.common.CommunicationTokenCredential;
      
      String userToken = "<user-access-token>";
      CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);
      ```
      
      ### Proactive Token Refresh (Long-lived Clients)
      
      ```java
      import com.azure.communication.common.CommunicationTokenRefreshOptions;
      import java.util.concurrent.Callable;
      
      Callable<String> tokenRefresher = () -> {
          // Call your server to get a fresh token
          return fetchNewTokenFromServer();
      };
      
      CommunicationTokenRefreshOptions refreshOptions = new CommunicationTokenRefreshOptions(tokenRefresher)
          .setRefreshProactively(true)
          .setInitialToken(currentToken);
      
      CommunicationTokenCredential credential = new CommunicationTokenCredential(refreshOptions);
      ```
      
      ### Token Refresh with HTTP Client
      
      ```java
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpResponse;
      import java.net.URI;
      import com.fasterxml.jackson.databind.JsonNode;
      import com.fasterxml.jackson.databind.ObjectMapper;
      
      public class TokenService {
          private final HttpClient httpClient = HttpClient.newHttpClient();
          private final ObjectMapper objectMapper = new ObjectMapper();
          private final String tokenEndpoint;
          private final String userId;
          
          public TokenService(String tokenEndpoint, String userId) {
              this.tokenEndpoint = tokenEndpoint;
              this.userId = userId;
          }
          
          public String fetchToken() throws Exception {
              HttpRequest request = HttpRequest.newBuilder()
                  .uri(URI.create(tokenEndpoint + "/api/token?userId=" + userId))
                  .GET()
                  .build();
              
              HttpResponse<String> response = httpClient.send(request, 
                  HttpResponse.BodyHandlers.ofString());
              
              if (response.statusCode() == 200) {
                  JsonNode json = objectMapper.readTree(response.body());
                  return json.get("token").asText();
              }
              throw new RuntimeException("Failed to fetch token: " + response.statusCode());
          }
          
          public CommunicationTokenCredential createCredential(String initialToken) {
              CommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(this::fetchToken)
                  .setRefreshProactively(true)
                  .setInitialToken(initialToken);
              
              return new CommunicationTokenCredential(options);
          }
      }
      ```
      
      ## Communication Identifiers
      
      ### CommunicationUserIdentifier
      
      ```java
      import com.azure.communication.common.CommunicationUserIdentifier;
      
      // Create identifier for ACS user
      CommunicationUserIdentifier user = new CommunicationUserIdentifier("8:acs:resource-id_user-id");
      String rawId = user.getId();
      ```
      
      ### PhoneNumberIdentifier
      
      ```java
      import com.azure.communication.common.PhoneNumberIdentifier;
      
      // E.164 format
      PhoneNumberIdentifier phone = new PhoneNumberIdentifier("+14255551234");
      String phoneNumber = phone.getPhoneNumber();  // "+14255551234"
      String rawId = phone.getRawId();              // "4:+14255551234"
      ```
      
      ### MicrosoftTeamsUserIdentifier
      
      ```java
      import com.azure.communication.common.MicrosoftTeamsUserIdentifier;
      import com.azure.communication.common.CommunicationCloudEnvironment;
      
      // Teams user
      MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier("<teams-user-id>")
          .setCloudEnvironment(CommunicationCloudEnvironment.PUBLIC);
      
      // Anonymous Teams user
      MicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier("<teams-user-id>")
          .setAnonymous(true);
      ```
      
      ### Identifier Parsing
      
      ```java
      import com.azure.communication.common.*;
      
      public class IdentifierParser {
          
          public CommunicationIdentifier parseIdentifier(String rawId) {
              if (rawId.startsWith("8:acs:")) {
                  return new CommunicationUserIdentifier(rawId);
              } else if (rawId.startsWith("4:")) {
                  String phone = rawId.substring(2);
                  return new PhoneNumberIdentifier(phone);
              } else if (rawId.startsWith("8:orgid:")) {
                  String teamsId = rawId.substring(8);
                  return new MicrosoftTeamsUserIdentifier(teamsId);
              } else {
                  return new UnknownIdentifier(rawId);
              }
          }
          
          public void processIdentifier(CommunicationIdentifier identifier) {
              if (identifier instanceof CommunicationUserIdentifier) {
                  CommunicationUserIdentifier user = (CommunicationUserIdentifier) identifier;
                  System.out.println("ACS User: " + user.getId());
                  
              } else if (identifier instanceof PhoneNumberIdentifier) {
                  PhoneNumberIdentifier phone = (PhoneNumberIdentifier) identifier;
                  System.out.println("Phone: " + phone.getPhoneNumber());
                  
              } else if (identifier instanceof MicrosoftTeamsUserIdentifier) {
                  MicrosoftTeamsUserIdentifier teams = (MicrosoftTeamsUserIdentifier) identifier;
                  System.out.println("Teams User: " + teams.getUserId());
                  System.out.println("Anonymous: " + teams.isAnonymous());
                  
              } else if (identifier instanceof UnknownIdentifier) {
                  UnknownIdentifier unknown = (UnknownIdentifier) identifier;
                  System.out.println("Unknown: " + unknown.getId());
              }
          }
      }
      ```
      
      ## Token Refresh Patterns
      
      ### Async Token Refresh
      
      ```java
      import java.util.concurrent.CompletableFuture;
      
      public class AsyncTokenService {
          
          public CompletableFuture<String> fetchTokenAsync() {
              return CompletableFuture.supplyAsync(() -> {
                  try {
                      // Simulate async HTTP call
                      Thread.sleep(100);
                      return "new-token-value";
                  } catch (InterruptedException e) {
                      Thread.currentThread().interrupt();
                      throw new RuntimeException(e);
                  }
              });
          }
          
          public CommunicationTokenCredential createCredential() {
              Callable<String> asyncRefresher = () -> {
                  CompletableFuture<String> future = fetchTokenAsync();
                  return future.get();
              };
              
              CommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(asyncRefresher)
                  .setRefreshProactively(true);
              
              return new CommunicationTokenCredential(options);
          }
      }
      ```
      
      ### Token Refresh with Retry
      
      ```java
      import java.util.concurrent.Callable;
      
      public class ResilientTokenService {
          private final String tokenEndpoint;
          private final int maxRetries;
          
          public ResilientTokenService(String tokenEndpoint, int maxRetries) {
              this.tokenEndpoint = tokenEndpoint;
              this.maxRetries = maxRetries;
          }
          
          public String fetchTokenWithRetry() throws Exception {
              Exception lastException = null;
              
              for (int attempt = 0; attempt < maxRetries; attempt++) {
                  try {
                      return fetchToken();
                  } catch (Exception e) {
                      lastException = e;
                      if (attempt < maxRetries - 1) {
                          long delay = (long) Math.pow(2, attempt) * 1000;
                          Thread.sleep(delay);
                      }
                  }
              }
              
              throw new RuntimeException("Failed to fetch token after " + maxRetries + " attempts", lastException);
          }
          
          private String fetchToken() throws Exception {
              // HTTP call to token endpoint
              return "token-value";
          }
          
          public CommunicationTokenCredential createCredential(String initialToken) {
              CommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(this::fetchTokenWithRetry)
                  .setRefreshProactively(true)
                  .setInitialToken(initialToken);
              
              return new CommunicationTokenCredential(options);
          }
      }
      ```
      
      ## Entra ID Authentication
      
      ### Teams Phone Extensibility
      
      ```java
      import com.azure.identity.InteractiveBrowserCredentialBuilder;
      import com.azure.identity.InteractiveBrowserCredential;
      import com.azure.communication.common.EntraCommunicationTokenCredentialOptions;
      import java.util.Arrays;
      import java.util.List;
      
      InteractiveBrowserCredential entraCredential = new InteractiveBrowserCredentialBuilder()
          .clientId("<your-client-id>")
          .tenantId("<your-tenant-id>")
          .redirectUrl("<your-redirect-uri>")
          .build();
      
      String resourceEndpoint = "https://<resource>.communication.azure.com";
      List<String> scopes = Arrays.asList(
          "https://auth.msft.communication.azure.com/TeamsExtension.ManageCalls"
      );
      
      EntraCommunicationTokenCredentialOptions entraOptions = 
          new EntraCommunicationTokenCredentialOptions(entraCredential, resourceEndpoint)
              .setScopes(scopes);
      
      CommunicationTokenCredential credential = new CommunicationTokenCredential(entraOptions);
      ```
      
      ## Complete Application Example
      
      ### Chat Client Factory with Token Management
      
      ```java
      import com.azure.communication.chat.ChatClient;
      import com.azure.communication.chat.ChatClientBuilder;
      import com.azure.communication.common.*;
      import java.util.concurrent.Callable;
      import java.util.concurrent.ConcurrentHashMap;
      import java.util.Map;
      
      public class ChatClientFactory {
          private final String endpoint;
          private final TokenService tokenService;
          private final Map<String, CommunicationTokenCredential> credentialCache = new ConcurrentHashMap<>();
          
          public ChatClientFactory(String endpoint, TokenService tokenService) {
              this.endpoint = endpoint;
              this.tokenService = tokenService;
          }
          
          public ChatClient createChatClient(String userId, String initialToken) {
              CommunicationTokenCredential credential = getOrCreateCredential(userId, initialToken);
              
              return new ChatClientBuilder()
                  .endpoint(endpoint)
                  .credential(credential)
                  .buildClient();
          }
          
          private CommunicationTokenCredential getOrCreateCredential(String userId, String initialToken) {
              return credentialCache.computeIfAbsent(userId, id -> {
                  Callable<String> refresher = () -> tokenService.fetchTokenForUser(id);
                  
                  CommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(refresher)
                      .setRefreshProactively(true)
                      .setInitialToken(initialToken);
                  
                  return new CommunicationTokenCredential(options);
              });
          }
          
          public void removeCredential(String userId) {
              CommunicationTokenCredential credential = credentialCache.remove(userId);
              if (credential != null) {
                  credential.close();
              }
          }
          
          public void close() {
              credentialCache.values().forEach(CommunicationTokenCredential::close);
              credentialCache.clear();
          }
      }
      
      class TokenService {
          public String fetchTokenForUser(String userId) {
              // Fetch token from your server
              return "token-for-" + userId;
          }
      }
      ```
      
      ### Multi-Tenant Communication Service
      
      ```java
      import com.azure.communication.common.*;
      import java.util.Map;
      import java.util.concurrent.ConcurrentHashMap;
      
      public class MultiTenantCommunicationService {
          private final Map<String, TenantContext> tenantContexts = new ConcurrentHashMap<>();
          
          public void registerTenant(String tenantId, String endpoint, String connectionString) {
              TenantContext context = new TenantContext(tenantId, endpoint, connectionString);
              tenantContexts.put(tenantId, context);
          }
          
          public CommunicationTokenCredential getCredentialForUser(String tenantId, String userId, String token) {
              TenantContext context = tenantContexts.get(tenantId);
              if (context == null) {
                  throw new IllegalArgumentException("Unknown tenant: " + tenantId);
              }
              
              return context.getOrCreateCredential(userId, token);
          }
          
          public CommunicationUserIdentifier createUserIdentifier(String tenantId, String userId) {
              // Format: 8:acs:resourceId_userId
              TenantContext context = tenantContexts.get(tenantId);
              String rawId = "8:acs:" + context.getResourceId() + "_" + userId;
              return new CommunicationUserIdentifier(rawId);
          }
          
          private static class TenantContext {
              private final String tenantId;
              private final String endpoint;
              private final String resourceId;
              private final Map<String, CommunicationTokenCredential> userCredentials = new ConcurrentHashMap<>();
              
              TenantContext(String tenantId, String endpoint, String connectionString) {
                  this.tenantId = tenantId;
                  this.endpoint = endpoint;
                  this.resourceId = extractResourceId(endpoint);
              }
              
              String getResourceId() {
                  return resourceId;
              }
              
              CommunicationTokenCredential getOrCreateCredential(String userId, String token) {
                  return userCredentials.computeIfAbsent(userId, id -> 
                      new CommunicationTokenCredential(token));
              }
              
              private String extractResourceId(String endpoint) {
                  // Extract resource ID from endpoint URL
                  return endpoint.replace("https://", "").replace(".communication.azure.com", "");
              }
          }
      }
      ```
      
      ## Environment Variables
      
      ```bash
      AZURE_COMMUNICATION_ENDPOINT=https://<resource>.communication.azure.com
      AZURE_COMMUNICATION_USER_TOKEN=<user-access-token>
      ```
      
      ## Best Practices
      
      1. **Proactive Refresh** - Always use `setRefreshProactively(true)` for long-lived clients
      2. **Token Security** - Never log or expose full tokens
      3. **Close Credentials** - Dispose of credentials when no longer needed
      4. **Error Handling** - Handle token refresh failures gracefully
      5. **Identifier Types** - Use specific identifier types, not raw strings
      6. **Connection Reuse** - Reuse credentials across requests to the same user
      7. **Caching** - Cache credentials per user to avoid unnecessary token refreshes
      
  • SKILL.md 9.5 KB
    ---
    name: azure-communication-common-java
    description: Azure Communication Services common utilities for Java. Use when working with CommunicationTokenCredential, user identifiers, token refresh, or shared authentication across ACS services.
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
      package: com.azure:azure-communication-common
    ---
    
    # Azure Communication Common (Java)
    
    Shared authentication utilities and data structures for Azure Communication Services.
    
    ## Installation
    
    ```xml
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-communication-common</artifactId>
        <version>1.4.0</version>
    </dependency>
    ```
    
    ## Key Concepts
    
    | Class | Purpose |
    |-------|---------|
    | `CommunicationTokenCredential` | Authenticate users with ACS services |
    | `CommunicationTokenRefreshOptions` | Configure automatic token refresh |
    | `CommunicationUserIdentifier` | Identify ACS users |
    | `PhoneNumberIdentifier` | Identify PSTN phone numbers |
    | `MicrosoftTeamsUserIdentifier` | Identify Teams users |
    | `UnknownIdentifier` | Generic identifier for unknown types |
    
    ## CommunicationTokenCredential
    
    ### Static Token (Short-lived Clients)
    
    ```java
    import com.azure.communication.common.CommunicationTokenCredential;
    
    // Simple static token - no refresh
    String userToken = "<user-access-token>";
    CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);
    
    // Use with Chat, Calling, etc.
    ChatClient chatClient = new ChatClientBuilder()
        .endpoint("https://<resource>.communication.azure.com")
        .credential(credential)
        .buildClient();
    ```
    
    ### Proactive Token Refresh (Long-lived Clients)
    
    ```java
    import com.azure.communication.common.CommunicationTokenRefreshOptions;
    import java.util.concurrent.Callable;
    
    // Token refresher callback - called when token is about to expire
    Callable<String> tokenRefresher = () -> {
        // Call your server to get a fresh token
        return fetchNewTokenFromServer();
    };
    
    // With proactive refresh
    CommunicationTokenRefreshOptions refreshOptions = new CommunicationTokenRefreshOptions(tokenRefresher)
        .setRefreshProactively(true)      // Refresh before expiry
        .setInitialToken(currentToken);    // Optional initial token
    
    CommunicationTokenCredential credential = new CommunicationTokenCredential(refreshOptions);
    ```
    
    ### Async Token Refresh
    
    ```java
    import java.util.concurrent.CompletableFuture;
    
    // Async token fetcher
    Callable<String> asyncRefresher = () -> {
        CompletableFuture<String> future = fetchTokenAsync();
        return future.get();  // Block until token is available
    };
    
    CommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(asyncRefresher)
        .setRefreshProactively(true);
    
    CommunicationTokenCredential credential = new CommunicationTokenCredential(options);
    ```
    
    ## Entra ID (Azure AD) Authentication
    
    ```java
    import com.azure.identity.InteractiveBrowserCredentialBuilder;
    import com.azure.communication.common.EntraCommunicationTokenCredentialOptions;
    import java.util.Arrays;
    import java.util.List;
    
    // For Teams Phone Extensibility
    InteractiveBrowserCredential entraCredential = new InteractiveBrowserCredentialBuilder()
        .clientId("<your-client-id>")
        .tenantId("<your-tenant-id>")
        .redirectUrl("<your-redirect-uri>")
        .build();
    
    String resourceEndpoint = "https://<resource>.communication.azure.com";
    List<String> scopes = Arrays.asList(
        "https://auth.msft.communication.azure.com/TeamsExtension.ManageCalls"
    );
    
    EntraCommunicationTokenCredentialOptions entraOptions = 
        new EntraCommunicationTokenCredentialOptions(entraCredential, resourceEndpoint)
            .setScopes(scopes);
    
    CommunicationTokenCredential credential = new CommunicationTokenCredential(entraOptions);
    ```
    
    ## Communication Identifiers
    
    ### CommunicationUserIdentifier
    
    ```java
    import com.azure.communication.common.CommunicationUserIdentifier;
    
    // Create identifier for ACS user
    CommunicationUserIdentifier user = new CommunicationUserIdentifier("8:acs:resource-id_user-id");
    
    // Get raw ID
    String rawId = user.getId();
    ```
    
    ### PhoneNumberIdentifier
    
    ```java
    import com.azure.communication.common.PhoneNumberIdentifier;
    
    // E.164 format phone number
    PhoneNumberIdentifier phone = new PhoneNumberIdentifier("+14255551234");
    
    String phoneNumber = phone.getPhoneNumber();  // "+14255551234"
    String rawId = phone.getRawId();              // "4:+14255551234"
    ```
    
    ### MicrosoftTeamsUserIdentifier
    
    ```java
    import com.azure.communication.common.MicrosoftTeamsUserIdentifier;
    
    // Teams user identifier
    MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier("<teams-user-id>")
        .setCloudEnvironment(CommunicationCloudEnvironment.PUBLIC);
    
    // For anonymous Teams users
    MicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier("<teams-user-id>")
        .setAnonymous(true);
    ```
    
    ### UnknownIdentifier
    
    ```java
    import com.azure.communication.common.UnknownIdentifier;
    
    // For identifiers of unknown type
    UnknownIdentifier unknown = new UnknownIdentifier("some-raw-id");
    ```
    
    ## Identifier Parsing
    
    ```java
    import com.azure.communication.common.CommunicationIdentifier;
    import com.azure.communication.common.CommunicationIdentifierModel;
    
    // Parse raw ID to appropriate type
    public CommunicationIdentifier parseIdentifier(String rawId) {
        if (rawId.startsWith("8:acs:")) {
            return new CommunicationUserIdentifier(rawId);
        } else if (rawId.startsWith("4:")) {
            String phone = rawId.substring(2);
            return new PhoneNumberIdentifier(phone);
        } else if (rawId.startsWith("8:orgid:")) {
            String teamsId = rawId.substring(8);
            return new MicrosoftTeamsUserIdentifier(teamsId);
        } else {
            return new UnknownIdentifier(rawId);
        }
    }
    ```
    
    ## Type Checking Identifiers
    
    ```java
    import com.azure.communication.common.CommunicationIdentifier;
    
    public void processIdentifier(CommunicationIdentifier identifier) {
        if (identifier instanceof CommunicationUserIdentifier) {
            CommunicationUserIdentifier user = (CommunicationUserIdentifier) identifier;
            System.out.println("ACS User: " + user.getId());
            
        } else if (identifier instanceof PhoneNumberIdentifier) {
            PhoneNumberIdentifier phone = (PhoneNumberIdentifier) identifier;
            System.out.println("Phone: " + phone.getPhoneNumber());
            
        } else if (identifier instanceof MicrosoftTeamsUserIdentifier) {
            MicrosoftTeamsUserIdentifier teams = (MicrosoftTeamsUserIdentifier) identifier;
            System.out.println("Teams User: " + teams.getUserId());
            System.out.println("Anonymous: " + teams.isAnonymous());
            
        } else if (identifier instanceof UnknownIdentifier) {
            UnknownIdentifier unknown = (UnknownIdentifier) identifier;
            System.out.println("Unknown: " + unknown.getId());
        }
    }
    ```
    
    ## Token Access
    
    ```java
    import com.azure.core.credential.AccessToken;
    
    // Get current token (for debugging/logging - don't expose!)
    CommunicationTokenCredential credential = new CommunicationTokenCredential(token);
    
    // Sync access
    AccessToken accessToken = credential.getToken();
    System.out.println("Token expires: " + accessToken.getExpiresAt());
    
    // Async access
    credential.getTokenAsync()
        .subscribe(token -> {
            System.out.println("Token: " + token.getToken().substring(0, 20) + "...");
            System.out.println("Expires: " + token.getExpiresAt());
        });
    ```
    
    ## Dispose Credential
    
    ```java
    // Clean up when done
    credential.close();
    
    // Or use try-with-resources
    try (CommunicationTokenCredential cred = new CommunicationTokenCredential(options)) {
        // Use credential
        chatClient.doSomething();
    }
    ```
    
    ## Cloud Environments
    
    ```java
    import com.azure.communication.common.CommunicationCloudEnvironment;
    
    // Available environments
    CommunicationCloudEnvironment publicCloud = CommunicationCloudEnvironment.PUBLIC;
    CommunicationCloudEnvironment govCloud = CommunicationCloudEnvironment.GCCH;
    CommunicationCloudEnvironment dodCloud = CommunicationCloudEnvironment.DOD;
    
    // Set on Teams identifier
    MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier("<user-id>")
        .setCloudEnvironment(CommunicationCloudEnvironment.GCCH);
    ```
    
    ## Environment Variables
    
    ```bash
    AZURE_COMMUNICATION_ENDPOINT=https://<resource>.communication.azure.com
    AZURE_COMMUNICATION_USER_TOKEN=<user-access-token>
    ```
    
    ## Best Practices
    
    1. **Proactive Refresh** - Always use `setRefreshProactively(true)` for long-lived clients
    2. **Token Security** - Never log or expose full tokens
    3. **Close Credentials** - Dispose of credentials when no longer needed
    4. **Error Handling** - Handle token refresh failures gracefully
    5. **Identifier Types** - Use specific identifier types, not raw strings
    
    ## Common Usage Patterns
    
    ```java
    // Pattern: Create credential for Chat/Calling client
    public ChatClient createChatClient(String token, String endpoint) {
        CommunicationTokenRefreshOptions refreshOptions = 
            new CommunicationTokenRefreshOptions(this::refreshToken)
                .setRefreshProactively(true)
                .setInitialToken(token);
        
        CommunicationTokenCredential credential = 
            new CommunicationTokenCredential(refreshOptions);
        
        return new ChatClientBuilder()
            .endpoint(endpoint)
            .credential(credential)
            .buildClient();
    }
    
    private String refreshToken() {
        // Call your token endpoint
        return tokenService.getNewToken();
    }
    ```
    
    ## Trigger Phrases
    
    - "ACS authentication", "communication token credential"
    - "user access token", "token refresh"
    - "CommunicationUserIdentifier", "PhoneNumberIdentifier"
    - "Azure Communication Services authentication"
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related