--- 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. package: com.azure:azure-communication-common --- # Azure Communication Common (Java) Shared authentication utilities and data structures for Azure Communication Services. ## Installation ```xml com.azure azure-communication-common 1.4.0 ``` ## 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 = ""; CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken); // Use with Chat, Calling, etc. ChatClient chatClient = new ChatClientBuilder() .endpoint("https://.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 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 asyncRefresher = () -> { CompletableFuture 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("") .tenantId("") .redirectUrl("") .build(); String resourceEndpoint = "https://.communication.azure.com"; List 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("") .setCloudEnvironment(CommunicationCloudEnvironment.PUBLIC); // For anonymous Teams users MicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier("") .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("") .setCloudEnvironment(CommunicationCloudEnvironment.GCCH); ``` ## Environment Variables ```bash AZURE_COMMUNICATION_ENDPOINT=https://.communication.azure.com AZURE_COMMUNICATION_USER_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"