你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

快速入门:使用 Microsoft Entra ID 进行身份验证

通过 Microsoft Entra ID 开始使用 Azure 通信服务。 通信服务标识和短信 SDK 支持Microsoft Entra 身份验证。

本快速入门介绍如何从支持 Active Directory 的 Azure 环境授权访问标识和短信 SDK。 它还介绍如何通过在开发环境中为工作创建服务主体来测试代码。

先决条件

其他先决条件

设置

将 Active Directory 用于其他 Azure 资源时,应使用托管标识。 若要了解如何为 Azure 资源启用托管标识,请参阅以下文章之一:

在开发环境中对已注册的应用程序进行身份验证

如果开发环境不支持通过 Web 浏览器进行单一登录或登录,则可以使用已注册的应用程序从开发环境进行身份验证。

创建 Microsoft Entra 已注册的应用程序

若要从 Azure CLI 创建已注册的应用程序,需要登录到要在其中执行作的 Azure 帐户。 为此,可以使用 az login 命令并在浏览器中输入凭据。 从 CLI 登录到 Azure 帐户后,我们可以调用 az ad sp create-for-rbac 该命令来创建已注册的应用程序和服务主体。

以下示例使用 Azure CLI 创建新的已注册应用程序:

az ad sp create-for-rbac --name <application-name> --role Contributor --scopes /subscriptions/<subscription-id>

此命令 az ad sp create-for-rbac 将返回 JSON 格式的服务主体属性列表。 复制这些值,以便在下一步中使用这些值来创建必要的环境变量。

{
    "appId": "generated-app-ID",
    "displayName": "service-principal-name",
    "name": "http://service-principal-uri",
    "password": "generated-password",
    "tenant": "tenant-ID"
}

重要

Azure 角色分配可能需要几分钟才能在系统中生效。

设置环境变量。

Azure 标识 SDK 会在运行时读取三个环境变量中的值,以对应用程序进行身份验证。 下表描述了要为每个环境变量设置的值。

环境变量 价值
AZURE_CLIENT_ID appId 来自生成的 JSON 的值
AZURE_TENANT_ID tenant 来自生成的 JSON 的值
AZURE_CLIENT_SECRET password 来自生成的 JSON 的值

重要

设置环境变量后,关闭并重新打开控制台窗口。 如果使用 Visual Studio 或其他开发环境,可能需要重启它才能注册新的环境变量。

设置这些变量后,应该能够使用代码中的 DefaultAzureCredential 对象向所选的服务客户端进行身份验证。

注释

GitHub 上查找此快速入门的最终代码

概述

本快速入门演示如何通过 Azure 服务主体使用托管标识来对 Azure 通信服务进行身份验证。 它提供了一些示例,用于发出 IP 语音(VoIP)呼叫和发送短信的访问令牌。

设置

新建 C# 应用程序

目标是在 C# 中创建新的控制台应用程序,以运行快速入门代码。 打开终端窗口(例如命令提示符、PowerShell 或 Bash),然后执行以下命令来创建一个名为 ActiveDirectoryAuthenticationQuickstart 的新控制台应用程序。

dotnet new console -o ActiveDirectoryAuthenticationQuickstart

此命令将生成一个简单的“Hello World”C# 项目,包括单个源文件: Program.cs

生成应用程序

导航到新创建的应用文件夹,并使用 dotnet build 以下命令编译应用程序:

cd ActiveDirectoryAuthenticationQuickstart
dotnet build

安装所需的 SDK 包

若要与 Azure 通信服务和 Azure 标识交互,请将以下 NuGet 包添加到项目:

dotnet add package Azure.Communication.Identity
dotnet add package Azure.Communication.Sms
dotnet add package Azure.Identity

更新Program.cs文件

若要使用已安装的 Azure SDK 包,请在using文件顶部包含以下指令Program.cs

using Azure.Identity;
using Azure.Communication.Identity;
using Azure.Communication.Sms;
using Azure.Core;
using Azure;

使用 DefaultAzureCredential 进行身份验证

在本快速入门中,我们将使用适用于开发和生产环境的 DefaultAzureCredential。 在 Program.cs 中类级别声明此凭据的实例:

private DefaultAzureCredential credential = new DefaultAzureCredential();

使用服务主体颁发令牌

将以下方法添加到 Program.cs 文件。 此方法使用 Azure 通信服务 SDK 颁发 VoIP 访问令牌:

public AccessToken CreateIdentityAndGetTokenAsync(Uri resourceEndpoint)
{
    var client = new CommunicationIdentityClient(resourceEndpoint, this.credential);
    var result = client.CreateUserAndToken(scopes: new[] { CommunicationTokenScope.VoIP });
    var (user, token) = response.Value;
    return token;
}

使用服务主体发送短信

若要演示如何发送短信,请将以下方法添加到 Program.cs 文件。 此方法使用 Azure 通信服务 SDK 发送短信:

public SmsSendResult SendSms(Uri resourceEndpoint, string from, string to, string message)
{
    SmsClient smsClient = new SmsClient(resourceEndpoint, this.credential);
    SmsSendResult sendResult = smsClient.Send(
            from: from,
            to: to,
            message: message,
            new SmsSendOptions(enableDeliveryReport: true) // optional
        );

    return sendResult;
}

编写 Main 方法

Main 文件的方法 Program.cs 中,添加代码以调用为颁发令牌和发送短信而创建的方法。 你的 Main 方法应如下所示:

static void Main(string[] args)
{
    // Replace <RESOURCE_NAME> with your Communication Services resource name,
    // for example: "https://<RESOURCE_NAME>.communication.azure.com".
    Uri endpoint = new("https://<RESOURCENAME>.communication.azure.com/");

    // Create an instance of the Program class to invoke instance methods.
    Program instance = new();

    Console.WriteLine("Retrieving new Access Token, using Service Principals");
    AccessToken response = instance.CreateIdentityAndGetTokenAsync(endpoint);
    Console.WriteLine($"Retrieved Access Token: {response.Token}");

    Console.WriteLine("Sending SMS using Service Principals");

    // Replace with your Azure Communication Services phone number and the target phone number.
    SmsSendResult result = instance.SendSms(endpoint, "<Your Azure Communication Services Phone Number>", "<The Phone Number you'd like to send the SMS to.>", "Hello from using Service Principals");
    Console.WriteLine($"Sms id: {result.MessageId}");
    Console.WriteLine($"Send Result Successful: {result.Successful}");
}

最终 Program.cs 文件应如下所示:

class Program
     {
          private DefaultAzureCredential credential = new DefaultAzureCredential();
          static void Main(string[] args)
          {
               // Replace <RESOURCE_NAME> with your Communication Services resource name,
               // for example: "https://<RESOURCE_NAME>.communication.azure.com".
               Uri endpoint = new("https://acstestingrifox.communication.azure.com/");

               // Create an instance of the Program class to invoke instance methods.
               Program instance = new();

               Console.WriteLine("Retrieving new Access Token, using Service Principals");
               AccessToken response = instance.CreateIdentityAndGetTokenAsync(endpoint);
               Console.WriteLine($"Retrieved Access Token: {response.Token}");

               Console.WriteLine("Sending SMS using Service Principals");

               // Replace with your Azure Communication Services phone number and the target phone number.
               SmsSendResult result = instance.SendSms(endpoint, "<Your Azure Communication Services Phone Number>", "<The Phone Number you'd like to send the SMS to.>", "Hello from Service Principals");
               Console.WriteLine($"Sms id: {result.MessageId}");
               Console.WriteLine($"Send Result Successful: {result.Successful}");
          }
          public AccessToken CreateIdentityAndGetTokenAsync(Uri resourceEndpoint)
          {
               var client = new CommunicationIdentityClient(resourceEndpoint, this.credential);
               var result = client.CreateUserAndToken(scopes: new[] { CommunicationTokenScope.VoIP });
               var (user, token) = response.Value;
               return token;
          }
          public SmsSendResult SendSms(Uri resourceEndpoint, string from, string to, string message)
          {
               SmsClient smsClient = new SmsClient(resourceEndpoint, this.credential);
               SmsSendResult sendResult = smsClient.Send(
                    from: from,
                    to: to,
                    message: message,
                    new SmsSendOptions(enableDeliveryReport: true) // optional
               );

               return sendResult;
          }
    }

运行程序

是时候运行应用程序并验证它是否检索访问令牌并发送短信了。 打开终端,导航到应用程序目录,然后运行:

     dotnet run

控制台输出应如下所示:

     Retrieving new Access Token, using Service Principals
     Retrieved Access Token: ...
     Sending SMS using Service Principals
     Sms id: ...
     Send Result Successful: True

注释

GitHub 上查找此快速入门的最终代码

设置

创建新的 Node.js 应用程序

打开终端或命令窗口,为应用创建一个新目录,并导航到该目录。

mkdir active-directory-authentication-quickstart && cd active-directory-authentication-quickstart

运行 npm init -y 以使用默认设置创建 package.json 文件。

npm init -y

安装 SDK 包

npm install @azure/communication-identity
npm install @azure/communication-common
npm install @azure/communication-sms
npm install @azure/identity

创建新文件

使用文本编辑器打开一个新文件并将其另存为 index.js,我们将代码放在此文件中。

使用 SDK 包

将以下 require 指令添加到 index.js 的顶部,以使用 Azure Identity 和 Azure Storage SDK。

const { DefaultAzureCredential } = require("@azure/identity");
const { CommunicationIdentityClient, CommunicationUserToken } = require("@azure/communication-identity");
const { SmsClient, SmsSendRequest } = require("@azure/communication-sms");

创建 DefaultAzureCredential

我们将在本快速入门中使用 DefaultAzureCredential 。 此凭据适用于生产和开发环境。 由于每个操作都需要它,我们就在文件 index.js 的顶部创建它。

    const credential = new DefaultAzureCredential();

创建标识并使用服务主体颁发令牌

接下来,我们将编写一个函数,用于创建新标识并颁发此标识的令牌,稍后我们将使用此函数来测试服务主体设置。

async function createIdentityAndIssueToken(resourceEndpoint) {
    const client = new CommunicationIdentityClient(resourceEndpoint, credential);
    return await client.createUserAndToken(["chat"]);
}

使用服务主体发送短信

现在,让我们编写一个函数,该函数使用服务主体发送短信:

async function sendSms(resourceEndpoint, fromNumber, toNumber, message) {
    const smsClient = new SmsClient(resourceEndpoint, credential);
    const sendRequest = {
        from: fromNumber,
        to: [toNumber],
        message: message
    };
    return await smsClient.send(
        sendRequest,
        {} //Optional SendOptions
    );
}

编写 main 函数

创建函数后,现在可以编写一个主函数来调用它们并演示服务主体的使用:

async function main() {
    // You can find your endpoint and access key from your resource in the Azure portal
    // e.g. "https://<RESOURCE_NAME>.communication.azure.com";
    const endpoint = "https://<RESOURCE_NAME>.communication.azure.com/"

    
    console.log("Retrieving new Access Token, using Service Principals");
    const result = await createIdentityAndIssueToken(endpoint);
    console.log(`Retrieved Access Token: ${result.token}`);

    console.log("Sending SMS using Service Principals");

    // You will need a phone number from your resource to send an SMS.
    const smsResult = await sendSms(endpoint, "<FROM NUMBER>", "<TO NUMBER>", "Hello from Service Principals");
    console.log(`SMS ID: ${smsResult[0].messageId}`);
    console.log(`Send Result Successful: ${smsResult[0].successful}`);
}

main();

最终 index.js 文件应如下所示:

const { DefaultAzureCredential } = require("@azure/identity");
const { CommunicationIdentityClient, CommunicationUserToken } = require("@azure/communication-identity");
const { SmsClient, SmsSendRequest } = require("@azure/communication-sms");

const credential = new DefaultAzureCredential();

async function createIdentityAndIssueToken(resourceEndpoint) {
    const client = new CommunicationIdentityClient(resourceEndpoint, credential);
    return await client.createUserAndToken(["chat"]);
}

async function sendSms(resourceEndpoint, fromNumber, toNumber, message) {
    const smsClient = new SmsClient(resourceEndpoint, credential);
    const sendRequest = {
        from: fromNumber,
        to: [toNumber],
        message: message
    };
    return await smsClient.send(
        sendRequest,
        {} //Optional SendOptions
    );
}

async function main() {
    // You can find your endpoint and access key from your resource in the Azure portal
    // e.g. "https://<RESOURCE_NAME>.communication.azure.com";
    const endpoint = "https://<RESOURCE_NAME>.communication.azure.com/"

    
    console.log("Retrieving new Access Token, using Service Principals");
    const result = await createIdentityAndIssueToken(endpoint);
    console.log(`Retrieved Access Token: ${result.token}`);

    console.log("Sending SMS using Service Principals");

    // You will need a phone number from your resource to send an SMS.
    const smsResult = await sendSms(endpoint, "<FROM NUMBER>", "<TO NUMBER>", "Hello from Service Principals");
    console.log(`SMS ID: ${smsResult[0].messageId}`);
    console.log(`Send Result Successful: ${smsResult[0].successful}`);
}

main();

运行程序

完成所有作后,可以通过从项目的目录中输入 node index.js 来运行该文件。 如果一切顺利,你应该会看到类似于以下内容的内容。

    $ node index.js
    Retrieving new Access Token, using Service Principals
    Retrieved Access Token: ey...Q
    Sending SMS using Service Principals
    SMS ID: ...
    Send Result Successful: true

Java 的其他先决条件

对于 Java,还需要:

注释

GitHub 上查找此快速入门的最终代码

设置

创建新的 Java 应用程序

打开终端或命令窗口。 导航到要在其中创建 Java 应用程序的目录。 运行以下命令以从 maven-archetype-quickstart 模板生成 Java 项目。

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

你会注意到,“生成”任务创建了与 artifactId 名称相同的目录。 在此目录下,src/main/java 目录包含项目源代码,src/test/java directory 包含测试源,pom.xml 文件是项目的项目对象模型 (POM)。

安装软件包

在文本编辑器中打开 pom.xml 文件。 将以下依赖项元素添加到依赖项组。

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-communication-identity</artifactId>
    <version>[1.4.0,)</version>
</dependency>
<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-communication-sms</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-identity</artifactId>
    <version>1.2.3</version>
</dependency>

使用 SDK 包

将以下 import 指令添加到代码,以使用 Azure 标识和 Azure 通信 SDK。

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

import java.util.*;

创建 DefaultAzureCredential

我们将在本快速入门中使用 DefaultAzureCredential 。 此凭据适用于生产和开发环境。 由于每个操作都需要它,让我们在 App.java 类中创建它。 将以下内容添加到类的 App.java 顶部。

private TokenCredential credential = new DefaultAzureCredentialBuilder().build();

使用服务主体颁发令牌

现在,我们将添加使用创建的凭据的代码来颁发 VoIP 访问令牌。 稍后我们将调用此代码;

    public AccessToken createIdentityAndGetTokenAsync(String endpoint) {
          CommunicationIdentityClient communicationIdentityClient = new CommunicationIdentityClientBuilder()
                    .endpoint(endpoint)
                    .credential(this.credential)
                    .buildClient();

          CommunicationUserIdentifierAndToken result =  communicationIdentityClient.createUserAndToken(new ArrayList<>(Arrays.asList(CommunicationTokenScope.CHAT)));
          return result.getUserToken();
    }

使用服务主体发送短信

作为另一个使用服务主体的示例,我们将添加此代码,该代码使用相同的凭据来发送短信:

     public SmsSendResult sendSms(String endpoint, String from, String to, String message) {
          SmsClient smsClient = new SmsClientBuilder()
                    .endpoint(endpoint)
                    .credential(this.credential)
                    .buildClient();

          // Send the message and check the response for a message id
          return smsClient.send(from, to, message);
     }

编写 Main 方法

你的 App.java 应该已经包含一个 Main 方法,让我们添加一些代码,以调用我们之前创建的代码来演示服务主体的应用:

    public static void main(String[] args) {
          App instance = new App();
          // You can find your endpoint and access key from your resource in the Azure portal
          // e.g. "https://<RESOURCE_NAME>.communication.azure.com";
          String endpoint = "https://<RESOURCE_NAME>.communication.azure.com/";

          System.out.println("Retrieving new Access Token, using Service Principals");
          AccessToken token = instance.createIdentityAndGetTokenAsync(endpoint);
          System.out.println("Retrieved Access Token: "+ token.getToken());

          System.out.println("Sending SMS using Service Principals");
          // You will need a phone number from your resource to send an SMS.
          SmsSendResult result = instance.sendSms(endpoint, "<FROM NUMBER>", "<TO NUMBER>", "Hello from Service Principals");
          System.out.println("Sms id: "+ result.getMessageId());
          System.out.println("Send Result Successful: "+ result.isSuccessful());
    }

最终的 App.java 应该是这样的:

package com.communication.quickstart;

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

import java.util.*;

public class App 
{

    private TokenCredential credential = new DefaultAzureCredentialBuilder().build();

    public SmsSendResult sendSms(String endpoint, String from, String to, String message) {
          SmsClient smsClient = new SmsClientBuilder()
               .endpoint(endpoint)
               .credential(this.credential)
               .buildClient();

          // Send the message and check the response for a message id
          return smsClient.send(from, to, message);
    }
    
    public AccessToken createIdentityAndGetTokenAsync(String endpoint) {
          CommunicationIdentityClient communicationIdentityClient = new CommunicationIdentityClientBuilder()
                    .endpoint(endpoint)
                    .credential(this.credential)
                    .buildClient();

          CommunicationUserIdentifierAndToken result =  communicationIdentityClient.createUserAndToken(new ArrayList<>(Arrays.asList(CommunicationTokenScope.CHAT)));
          return result.getUserToken();
    }

    public static void main(String[] args) {
          App instance = new App();
          // You can find your endpoint and access key from your resource in the Azure portal
          // e.g. "https://<RESOURCE_NAME>.communication.azure.com";
          String endpoint = "https://<RESOURCE_NAME>.communication.azure.com/";

          System.out.println("Retrieving new Access Token, using Service Principals");
          AccessToken token = instance.createIdentityAndGetTokenAsync(endpoint);
          System.out.println("Retrieved Access Token: "+ token.getToken());

          System.out.println("Sending SMS using Service Principals");
          // You will need a phone number from your resource to send an SMS.
          SmsSendResult result = instance.sendSms(endpoint, "<FROM NUMBER>", "<TO NUMBER>", "Hello from Service Principals");
          System.out.println("Sms id: "+ result.getMessageId());
          System.out.println("Send Result Successful: "+ result.isSuccessful());
    }
}

运行代码

导航到包含 pom.xml 文件的目录,并使用以下 命令编译该项目。

mvn compile

然后,生成包。

mvn package

运行以下 mvn 命令以执行应用。

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

最终输出应如下所示:

Retrieving new Access Token, using Service Principals
Retrieved Access Token: ey..A
Sending SMS using using Service Principals
Sms id: ...
Send Result Successful: true

注释

GitHub 上查找此快速入门的最终代码

设置

创建新的 Python 应用程序

让我们为应用程序设置工作目录。 为此,请打开终端或命令窗口,创建新的目录,然后导航到它:

mkdir active-directory-authentication-quickstart && cd active-directory-authentication-quickstart

安装 SDK 包

接下来,我们需要安装所需的 Azure SDK 包。 运行以下命令:

pip install azure-identity
pip install azure-communication-identity
pip install azure-communication-sms

创建新文件

现在,我们需要一个 Python 文件来保存代码。 在您的目录中创建并保存一个名为 authentication.py 的新文件。

使用 SDK 包

下一个目标是导入必要的 Azure SDK 模块来处理标识和短信。 在文件顶部添加以下语句:

from azure.identity import DefaultAzureCredential
from azure.communication.identity import CommunicationIdentityClient
from azure.communication.sms import SmsClient

创建 DefaultAzureCredential

我们需要为生产和开发环境初始化凭据。

将这行 DefaultAzureCredential 放在之前插入的行之后。

     credential = DefaultAzureCredential()

创建标识并使用服务主体颁发令牌

创建标识并请求语音网络协议(VoIP)访问令牌。

def create_identity_and_get_token(resource_endpoint):
     client = CommunicationIdentityClient(resource_endpoint, credential)
     user, token_response = client.create_user_and_token(scopes=["voip"])

     return token_response

使用服务主体发送短信

或者,可以使用你的凭据发送短信服务 (SMS),如以下示例所示:

def send_sms(resource_endpoint, from_phone_number, to_phone_number, message_content):
     sms_client = SmsClient(resource_endpoint, credential)

     sms_client.send(
          from_=from_phone_number,
          to_=[to_phone_number],
          message=message_content,
          enable_delivery_report=True  # optional property
     )

编写主代码

现在,我们拥有所有所需的代码块,以便执行创建身份、获取访问令牌和发送短信的功能。

包括调用函数的主要代码:

# Retrieve your endpoint and access key from your resource in the Azure portal
# For example: "https://<RESOURCE_NAME>.communication.azure.com"
endpoint = "https://<RESOURCE_NAME>.communication.azure.com/"

print("Retrieving new Access Token, using Service Principals");
result = create_identity_and_get_token(endpoint);
print(f'Retrieved Access Token: {result.token}');

print("Sending SMS using Service Principals");

# Provide a valid phone number from your Azure resource to send an SMS.
sms_result = send_sms(endpoint, "<FROM_NUMBER>", "<TO_NUMBER>", "Hello from Service Principals");
print(f'SMS ID: {sms_result[0].message_id}');
print(f'Send Result Successful: {sms_result[0].successful}');

经过所有更改后,authentication.py 就是这样:

from azure.identity import DefaultAzureCredential
from azure.communication.identity import CommunicationIdentityClient
from azure.communication.sms import SmsClient

credential = DefaultAzureCredential()

def create_identity_and_get_token(resource_endpoint):
     client = CommunicationIdentityClient(resource_endpoint, credential)
     user, token_response = client.create_user_and_token(scopes=["voip"])

     return token_response

def send_sms(resource_endpoint, from_phone_number, to_phone_number, message_content):
     sms_client = SmsClient(resource_endpoint, credential)

     response = sms_client.send(
          from_=from_phone_number,
          to=[to_phone_number],
          message=message_content,
          enable_delivery_report=True  # optional property
     )
     return response

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

print("Retrieving new Access Token, using Service Principals");
result = create_identity_and_get_token(endpoint);
print(f'Retrieved Access Token: {result.token}');

print("Sending SMS using Service Principals");

# You will need a phone number from your resource to send an SMS.
sms_result = send_sms(endpoint, "<FROM_NUMBER>", "<TO_NUMBER>", "Hello from Service Principals");
print(f'SMS ID: {sms_result[0].message_id}');
print(f'Send Result Successful: {sms_result[0].successful}');

运行程序

是时候执行 Python 脚本来验证功能了。 使用以下命令从项目的目录中运行文件:

python authentication.py

如果成功,则会看到如下所示的输出:

    $ python authentication.py
    Retrieving new Access Token, using Service Principals
    Retrieved Access Token: ...
    Sending SMS using Service Principals
    SMS ID: ...
    Send Result Successful: true

后续步骤