azure-communication-common-java

--- Utilitaires courants d'Azure Communication Services pour Java. À utiliser lors du travail avec CommunicationTokenCredential, des identifiants d'utilisateur, de l'actualisation des jetons ou d'une authentification partagée dans les services ACS.

npx skills add https://github.com/microsoft/skills --skill azure-communication-common-java

Azure Communication Common (Java)

Utilitaires d'authentification partagés et structures de données pour Azure Communication Services.

Installation

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

Concepts Clés

Classe Objectif
CommunicationTokenCredential Authentifier les utilisateurs avec les services ACS
CommunicationTokenRefreshOptions Configurer l'actualisation automatique des jetons
CommunicationUserIdentifier Identifier les utilisateurs ACS
PhoneNumberIdentifier Identifier les numéros de téléphone PSTN
MicrosoftTeamsUserIdentifier Identifier les utilisateurs Teams
UnknownIdentifier Identifiant générique pour les types inconnus

CommunicationTokenCredential

Jeton Statique (Clients de Courte Durée)

import com.azure.communication.common.CommunicationTokenCredential;

// Jeton statique simple - pas d'actualisation
String userToken = "<user-access-token>";
CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);

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

Actualisation Proactive des Jetons (Clients de Longue Durée)

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

// Rappel d'actualisation du jeton - appelé quand le jeton est sur le point d'expirer
Callable<String> tokenRefresher = () -> {
    // Appelez votre serveur pour obtenir un jeton frais
    return fetchNewTokenFromServer();
};

// Avec actualisation proactive
CommunicationTokenRefreshOptions refreshOptions = new CommunicationTokenRefreshOptions(tokenRefresher)
    .setRefreshProactively(true)      // Actualiser avant l'expiration
    .setInitialToken(currentToken);    // Jeton initial optionnel

CommunicationTokenCredential credential = new CommunicationTokenCredential(refreshOptions);

Actualisation Asynchrone des Jetons

import java.util.concurrent.CompletableFuture;

// Récupérateur de jeton asynchrone
Callable<String> asyncRefresher = () -> {
    CompletableFuture<String> future = fetchTokenAsync();
    return future.get();  // Bloquer jusqu'à ce que le jeton soit disponible
};

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

CommunicationTokenCredential credential = new CommunicationTokenCredential(options);

Authentification Entra ID (Azure AD)

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

// Pour 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);

Identifiants de Communication

CommunicationUserIdentifier

import com.azure.communication.common.CommunicationUserIdentifier;

// Créer un identifiant pour l'utilisateur ACS
CommunicationUserIdentifier user = new CommunicationUserIdentifier("8:acs:resource-id_user-id");

// Obtenir l'ID brut
String rawId = user.getId();

PhoneNumberIdentifier

import com.azure.communication.common.PhoneNumberIdentifier;

// Numéro de téléphone au format E.164
PhoneNumberIdentifier phone = new PhoneNumberIdentifier("+14255551234");

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

MicrosoftTeamsUserIdentifier

import com.azure.communication.common.MicrosoftTeamsUserIdentifier;

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

// Pour les utilisateurs Teams anonymes
MicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier("<teams-user-id>")
    .setAnonymous(true);

UnknownIdentifier

import com.azure.communication.common.UnknownIdentifier;

// Pour les identifiants de type inconnu
UnknownIdentifier unknown = new UnknownIdentifier("some-raw-id");

Analyse des Identifiants

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

// Analyser l'ID brut pour obtenir le type approprié
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);
    }
}

Vérification de Type d'Identifiants

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());
    }
}

Accès au Jeton

import com.azure.core.credential.AccessToken;

// Obtenir le jeton actuel (pour le débogage/la journalisation - ne pas exposer !)
CommunicationTokenCredential credential = new CommunicationTokenCredential(token);

// Accès synchrone
AccessToken accessToken = credential.getToken();
System.out.println("Token expires: " + accessToken.getExpiresAt());

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

Supprimer les Identifiants

// Nettoyer quand c'est fait
credential.close();

// Ou utiliser try-with-resources
try (CommunicationTokenCredential cred = new CommunicationTokenCredential(options)) {
    // Utiliser les identifiants
    chatClient.doSomething();
}

Environnements Cloud

import com.azure.communication.common.CommunicationCloudEnvironment;

// Environnements disponibles
CommunicationCloudEnvironment publicCloud = CommunicationCloudEnvironment.PUBLIC;
CommunicationCloudEnvironment govCloud = CommunicationCloudEnvironment.GCCH;
CommunicationCloudEnvironment dodCloud = CommunicationCloudEnvironment.DOD;

// Définir sur l'identifiant Teams
MicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier("<user-id>")
    .setCloudEnvironment(CommunicationCloudEnvironment.GCCH);

Variables d'Environnement

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

Bonnes Pratiques

  1. Actualisation Proactive - Toujours utiliser setRefreshProactively(true) pour les clients de longue durée
  2. Sécurité des Jetons - Ne jamais journaliser ou exposer les jetons complets
  3. Fermer les Identifiants - Supprimer les identifiants quand ils ne sont plus nécessaires
  4. Gestion des Erreurs - Gérer les échecs d'actualisation des jetons avec élégance
  5. Types d'Identifiants - Utiliser les types d'identifiants spécifiques, pas les chaînes brutes

Modèles d'Utilisation Courants

// Modèle : Créer des identifiants pour le client Chat/Calling
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() {
    // Appeler votre point de terminaison de jeton
    return tokenService.getNewToken();
}

Expressions Déclencheurs

  • "Authentification ACS", "identifiants de jeton de communication"
  • "Jeton d'accès utilisateur", "actualisation des jetons"
  • "CommunicationUserIdentifier", "PhoneNumberIdentifier"
  • "Authentification Azure Communication Services"