移轉應用程式以搭配 Azure 服務匯流排使用無密碼連線
您必須使用帳戶存取金鑰或無密碼連線來驗證應用程式對 Azure 服務匯流排的要求。 不過,您應該盡可能在應用程式中排定無密碼連線的優先順序。 本教學課程將探討如何從傳統驗證方法移轉為更安全的無密碼連線。
與存取金鑰相關聯的安全性風險
下列程式碼範例示範如何使用包含存取金鑰的連接字串來連線到 Azure 服務匯流排。 當您建立服務匯流排時,Azure 會自動產生這些金鑰和連接字串。 許多開發人員傾向於此解決方案,因為感覺很像過去使用的選項。 如果您的應用程式目前使用連接字串,請考慮使用本文所述的步驟來移轉至無密碼連線。
await using ServiceBusClient client = new("<CONNECTION-STRING>");
client, err := azservicebus.NewClientFromConnectionString(
"<CONNECTION-STRING>",
nil)
if err != nil {
// handle error
}
JMS:
ConnectionFactory factory = new ServiceBusJmsConnectionFactory(
"<CONNECTION-STRING>",
new ServiceBusJmsConnectionFactorySettings());
接收者用戶端:
ServiceBusReceiverClient receiver = new ServiceBusClientBuilder()
.connectionString("<CONNECTION-STRING>")
.receiver()
.topicName("<TOPIC-NAME>")
.subscriptionName("<SUBSCRIPTION-NAME>")
.buildClient();
傳送者用戶端:
ServiceBusSenderClient client = new ServiceBusClientBuilder()
.connectionString("<CONNECTION-STRING>")
.sender()
.queueName("<QUEUE-NAME>")
.buildClient();
const client = new ServiceBusClient("<CONNECTION-STRING>");
client = ServiceBusClient(
fully_qualified_namespace = "<CONNECTION-STRING>"
)
使用連接字串時應該要特別小心。 開發人員必須盡可能避免在不安全的地方公開金鑰。 能夠存取金鑰存取權的任何人都可以進行驗證。 例如,如果帳戶金鑰意外簽入原始檔控制、透過不安全的電子郵件傳送、貼到錯誤的聊天中,或被不應該有權限的人看到,則會引起惡意使用者存取應用程式的風險。 相反地,請考慮將應用程式更新為使用無密碼連線。
移轉至無密碼連線
許多 Azure 服務透過 Microsoft Entra ID 和角色型存取控制 (RBAC) 來支援無密碼連線。 這些技術提供強固的安全性功能,而且可以使用 Azure 身分識別用戶端程式庫中的 DefaultAzureCredential
來實作。
重要
有些語言必須在程式碼中明確實作 DefaultAzureCredential
,而有些語言則透過基礎外掛程式或驅動程式在內部使用 DefaultAzureCredential
。
DefaultAzureCredential
支援多個驗證方法,並在執行階段自動判斷應該使用何者。 此方法可讓您的應用程式在不同的環境中 (本機開發或實際執行環境) 使用不同的驗證方法,而不需要實作環境特有的程式碼。
在 Azure 身分識別程式庫概觀中可以找到 DefaultAzureCredential
搜尋認證時的順序和位置,而且隨語言而有所不同。 例如,在本機使用 .NET 時,DefaultAzureCredential
通常會使用開發人員用來登入 Visual Studio、Azure CLI 或 Azure PowerShell 的帳戶進行驗證。 當應用程式部署至 Azure 時,DefaultAzureCredential
會自動探索並使用相關聯裝載服務的受控識別,例如 Azure App Service。 此轉移不需要變更程式碼。
注意
受控識別提供安全性身分識別來代表應用程式或服務。 身分識別由 Azure 平台負責管理,因此您不需要佈建或輪替任何密碼。 您可以在概觀文件中深入了解受控識別。
下列程式碼範例示範如何使用無密碼連線來連線至服務匯流排。 下一節詳細描述如何為特定服務移轉至此設定。
.NET 應用程式可以將 DefaultAzureCredential
的執行個體傳遞至服務用戶端類別的建構函式。 DefaultAzureCredential
會自動探索該環境中可用的認證。
client = new ServiceBusClient(
"<NAMESPACE-NAME>.servicebus.windows.net",
new DefaultAzureCredential());
將應用程式移轉為使用無密碼驗證的步驟
下列步驟說明如何將現有的應用程式移轉為使用無密碼連線,而不是金鑰型解決方案。 您首先會設定本機開發環境,然後將這些概念套用至 Azure 應用程式裝載環境。 不論您是直接使用存取金鑰,還是透過連接字串,這些相同的移轉步驟都應該適用。
在本機開發時,請確定存取服務匯流排的使用者帳戶具有正確的權限。 在此範例中,您將使用 Azure 服務匯流排資料擁有者角色來傳送和接收資料,但也會提供更細微的角色。 若要指派此角色給您自己,您需要被指派使用者存取管理員角色,或另一個包含 Microsoft.Authorization/roleAssignments/write 動作的角色。 您可以使用 Azure 入口網站、Azure CLI 或 Azure PowerShell,將 Azure RBAC 角色指派給使用者。 您可以在範圍概觀頁面上深入了解角色指派的可用範圍。
在此案例中,您會將權限指派給使用者帳戶 (以特定服務匯流排命名空間為範圍),以遵循最低權限原則。 此做法只為使用者提供所需的最低權限,並建立更安全的實際執行環境。
下列範例會將 Azure 服務匯流排資料擁有者角色指派給您的使用者帳戶,允許您傳送和接收資料。
重要
在大部分情況下,角色指派在 Azure 中傳播只需要一兩分鐘,但在罕見情況下,可能需要長達八分鐘。 如果您第一次執行程式碼時收到驗證錯誤,請稍候片刻再試一次。
在 Azure 入口網站中,使用主要搜尋列或左側導覽找出您的服務匯流排命名空間。
在服務匯流排概觀頁面上,從左側功能表中選取 [存取控制 (IAM)]。
在 [存取控制 (IAM)] 頁面上,選取 [角色指派] 索引標籤。
從頂端功能表選取 [+ 新增],然後從產生的下拉功能表中選取 [新增角色指派]。
使用搜尋方塊,從結果篩選出所需的角色。 在此範例中,搜尋「Azure 服務匯流排資料擁有者」選取相符的結果,然後選擇 [下一步]。
在 [存取權指派對象為] 下,選取 [使用者、群組或服務主體],然後選擇 [+ 選取成員]。
在對話方塊中,搜尋 Microsoft Entra 使用者名稱 (通常是您的 user@domain 電子郵件地址),然後在對話方塊底部選擇 [選取]。
選取 [檢閱 + 指派] 以移至最終頁面,然後再次選取 [檢閱 + 指派] 以完成此程序。
若要使用 Azure CLI 在資源層級指派角色,您必須先使用 az servicesbus namespace show
命令擷取資源識別碼。 您可以使用 --query
參數來篩選輸出屬性。
az servicebus namespace show --resource-group '<your-resource-group-name>' --name '<your-service-bus-namespace>' --query id
複製上述命令的輸出 ID
。 接著,您可以使用 Azure CLI 的 az role 命令來指派角色。
az role assignment create --assignee "<user@domain>" \
--role "Azure Service Bus Data Owner" \
--scope "<your-resource-id>"
若要使用 Azure PowerShell 在資源層級指派角色,您必須先使用 Get-AzResource
命令擷取資源識別碼。
Get-AzResource -ResourceGroupName "<yourResourceGroupname>" -Name "<yourServiceBusName>"
複製上述命令輸出的 ID
值。 接著,您可以在 PowerShell 中使用 New-AzRoleAssignment 命令來指派角色。
New-AzRoleAssignment -SignInName <user@domain> `
-RoleDefinitionName "Azure Service Bus Data Owner" `
-Scope <yourServiceBusId>
登入並將應用程式程式碼移轉為使用無密碼連線
針對本機開發,請確定為服務匯流排命名空間使用您指派角色的相同 Microsoft Entra 帳戶進行驗證。 您可以透過 Azure CLI、Visual Studio、Azure PowerShell 或其他工具 (例如 IntelliJ) 進行驗證。
針對本機開發,請確定使用您指派角色的相同 Microsoft Entra 帳戶進行驗證。 您可以透過 Azure CLI 或 Azure PowerShell 這類熱門開發工具來進行驗證。 您可以用來驗證的開發工具會因語言而異。
使用下列命令透過 Azure CLI 登入 Azure:
az login
選取 Visual Studio 右上角的 [登入] 按鈕。
使用您先前指派角色的 Microsoft Entra 帳戶來登入。
必須安裝 Azure CLI,才能透過 Visual Studio Code 使用 DefaultAzureCredential
。
在 Visual Studio Code 的主功能表上,瀏覽至 [終端機] > [新增終端機]。
使用下列命令透過 Azure CLI 登入 Azure:
az login
使用 PowerShell 透過下列命令登入 Azure:
Connect-AzAccount
接下來,將您的程式碼更新為使用無密碼連線。
若要在 .NET 應用程式中使用 DefaultAzureCredential
,請安裝 Azure.Identity
套件:
dotnet add package Azure.Identity
在檔案頂端,新增下列程式碼:
using Azure.Identity;
識別哪個程式碼建立 ServiceBusClient
物件以連線至 Azure 服務匯流排。 將程式碼更新為符合下列範例:
var serviceBusNamespace = $"{namespace}.servicebus.windows.net";
ServiceBusClient client = new(
serviceBusNamespace,
new DefaultAzureCredential());
若要在 Go 應用程式中使用 DefaultAzureCredential
,請安裝 azidentity
模組:
go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
在檔案頂端,新增下列程式碼:
import (
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
)
在程式碼中識別哪些位置建立 Client
執行個體以連線至 Azure 服務匯流排。 將程式碼更新為符合下列範例:
credential, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
// handle error
}
serviceBusNamespace := fmt.Sprintf(
"%s.servicebus.windows.net",
namespace)
client, err := azservicebus.NewClient(serviceBusNamespace, credential, nil)
if err != nil {
// handle error
}
若要使用 DefaultAzureCredential
:
在 JMS 應用程式中,將至少 1.0.0 版的 azure-servicebus-jms
套件新增至您的應用程式:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus-jms</artifactId>
<version>1.0.0</version>
</dependency>
在 Java 應用程式中,透過下列其中一種方式來安裝 azure-identity
套件:
在檔案頂端,新增下列程式碼:
import com.azure.identity.DefaultAzureCredentialBuilder;
更新連線至 Azure 服務匯流排的程式碼:
在 JMS 應用程式中,識別哪個程式碼建立 ServiceBusJmsConnectionFactory
物件以連線至 Azure 服務匯流排。 將程式碼更新為符合下列範例:
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.build();
String serviceBusNamespace =
namespace + ".servicebus.windows.net";
ConnectionFactory factory = new ServiceBusJmsConnectionFactory(
credential,
serviceBusNamespace,
new ServiceBusJmsConnectionFactorySettings());
在 Java 應用程式中,識別哪個程式碼建立服務匯流排傳送者或接收者用戶端物件,以連線到 Azure 服務匯流排。 將您的程式碼更新為符合下列其中一個範例:
接收者用戶端:
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.build();
String serviceBusNamespace =
namespace + ".servicebus.windows.net";
ServiceBusReceiverClient receiver = new ServiceBusClientBuilder()
.credential(serviceBusNamespace, credential)
.receiver()
.topicName("<TOPIC-NAME>")
.subscriptionName("<SUBSCRIPTION-NAME>")
.buildClient();
傳送者用戶端:
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.build();
String serviceBusNamespace =
namespace + ".servicebus.windows.net";
ServiceBusSenderClient client = new ServiceBusClientBuilder()
.credential(serviceBusNamespace, credential)
.sender()
.queueName("<QUEUE-NAME>")
.buildClient();
若要在 Node.js 應用程式中使用 DefaultAzureCredential
,請安裝 @azure/identity
套件:
npm install --save @azure/identity
在檔案頂端,新增下列程式碼:
const { DefaultAzureCredential } = require("@azure/identity");
識別哪個程式碼建立 ServiceBusClient
物件以連線至 Azure 服務匯流排。 將程式碼更新為符合下列範例:
const credential = new DefaultAzureCredential();
const serviceBusNamespace = `${namespace}.servicebus.windows.net`;
const client = new ServiceBusClient(
serviceBusNamespace,
credential
);
若要在 Python 應用程式中使用 DefaultAzureCredential
,請安裝 azure-identity
套件:
pip install azure-identity
在檔案頂端,新增下列程式碼:
from azure.identity import DefaultAzureCredential
識別哪個程式碼建立 ServiceBusClient
物件以連線至 Azure 服務匯流排。 將程式碼更新為符合下列範例:
credential = DefaultAzureCredential()
service_bus_namespace = "%s.servicebus.windows.net" % namespace
client = ServiceBusClient(
fully_qualified_namespace = service_bus_namespace,
credential = credential
)
在本機執行應用程式
完成這些程式碼變更之後,請在本機執行您的應用程式。 新的組態應該會挑選您的本機認證,例如 Azure CLI、Visual Studio 或 IntelliJ。 您在 Azure 中指派給本機開發人員使用者的角色,可讓您的應用程式在本機連線到 Azure 服務。
一旦您的應用程式設定為使用無密碼連線並在本機執行,相同的程式碼在部署至 Azure 之後就可以向 Azure 服務進行驗證。 例如,如果應用程式部署至已啟用受控識別的 Azure App Service 執行個體,則可以連線到 Azure 服務匯流排。
使用 Azure 入口網站建立受控識別
下列步驟示範如何為各種虛擬主機服務建立系統指派的受控識別。 受控識別可以使用您先前設定的應用程式設定,安全地連線至其他 Azure 服務。
某些應用程式裝載環境支援服務連接器,可協助您將 Azure 計算服務連線至其他支援服務。 服務連接器會自動設定網路設定和連線資訊。 您可以在概觀頁面上深入了解服務連接器及支援的案例。
目前支援下列計算服務:
- Azure App Service
- Azure Spring Cloud
- Azure 容器應用程式 (預覽)
針對此移轉指南,您將使用 App 應用程式,但在 Azure Spring Apps 和 Azure 容器應用程式上的步驟也都類似。
注意
Azure Spring 應用程式目前僅支援使用連接字串的服務連接器。
在 App Service 的主要概觀頁面上,從左側導覽中選取 [服務連接器]。
從頂端功能表選取 [+ 建立],[建立連線] 面板隨即開啟。 輸入下列值:
- 服務類型:選擇 [服務匯流排]。
- 訂用帳戶:選取您要使用的訂用帳戶。
- 連線名稱:輸入連線的名稱,例如 connector_appservice_servicebus。
- 用戶端類型:保持選取預設值,或選擇您想要使用的特定用戶端。
選取 [下一步:驗證]。
確定已選取 [系統指派的受控識別 (建議)],然後選擇 [下一步:網路]。
保持選取預設值,然後選擇 [下一步:檢閱 + 建立]。
在 Azure 驗證您的設定之後,選取 [建立]。
服務連接器會自動為應用程式服務建立系統指派的受控識別。 連接器也會將所選服務匯流排的 Azure 服務匯流排資料擁有者角色指派給受控識別。
在 Azure App Service 執行個體的主要概觀頁面上,從左側導覽中選取 [身分識別]。
在 [系統指派] 索引標籤下,請務必將 [狀態] 欄位設定為 [開啟]。 系統指派的身分識別由 Azure 在內部管理,可替您處理管理工作。 身分識別的詳細資料和識別碼絕對不會在程式碼中公開。
在 Azure Spring 應用程式執行個體的主要概觀頁面上,從左側導覽中選取 [身分識別]。
在 [系統指派] 索引標籤下,請務必將 [狀態] 欄位設定為 [開啟]。 系統指派的身分識別由 Azure 在內部管理,可替您處理管理工作。 身分識別的詳細資料和識別碼絕對不會在程式碼中公開。
在 Azure 容器應用程式執行個體的主要概觀頁面上,從左側導覽中選取 [身分識別]。
在 [系統指派] 索引標籤下,請務必將 [狀態] 欄位設定為 [開啟]。 系統指派的身分識別由 Azure 在內部管理,可替您處理管理工作。 身分識別的詳細資料和識別碼絕對不會在程式碼中公開。
在虛擬機器的主要概觀頁面上,從左側導覽中選取 [身分識別]。
在 [系統指派] 索引標籤下,請務必將 [狀態] 欄位設定為 [開啟]。 系統指派的身分識別由 Azure 在內部管理,可替您處理管理工作。 身分識別的詳細資料和識別碼絕對不會在程式碼中公開。
或者,您也可以使用 Azure CLI 在 Azure 裝載環境中啟用受控識別。
您可以使用服務連接器,以 Azure CLI 建立 Azure 計算裝載環境和目標服務之間的連線。 CLI 會自動處理建立受控識別,並指派適當的角色,如入口網站指示中所述。
如果您使用 Azure App Service,請使用 az webapp connection
命令:
az webapp connection create servicebus \
--resource-group <resource-group-name> \
--name <webapp-name> \
--target-resource-group <target-resource-group-name> \
--namespace <target-service-bus-namespace> \
--system-identity
如果您使用 Azure Spring 應用程式,請使用 az spring connection
命令:
az spring connection create servicebus \
--resource-group <resource-group-name> \
--service <service-instance-name> \
--app <app-name> \
--deployment <deployment-name> \
--target-resource-group <target-resource-group> \
--namespace <target-service-bus-namespace> \
--system-identity
如果您使用 Azure 容器應用程式,請使用 az containerapp connection
命令:
az containerapp connection create servicebus \
--resource-group <resource-group-name> \
--name <webapp-name> \
--target-resource-group <target-resource-group-name> \
--namespace <target-service-bus-namespace> \
--system-identity
您可以使用 az webapp identity assign 命令,將受控識別指派給 Azure App Service 執行個體。
az webapp identity assign \
--resource-group <resource-group-name> \
--name <webapp-name>
您可以使用 az spring app identity assign 命令,將受控識別指派給 Azure Spring 應用程式執行個體。
az spring app identity assign \
--resource-group <resource-group-name> \
--name <app-name> \
--service <service-name>
您可以使用 az container app identity assign 命令,將受控識別指派給 Azure 容器應用程式執行個體。
az containerapp identity assign \
--resource-group <resource-group-name> \
--name <app-name>
您可以使用 az vm identity assign 命令,將受控識別指派給虛擬機器。
az vm identity assign \
--resource-group <resource-group-name> \
--name <virtual-machine-name>
您可以使用 az aks update命令,將受控識別指派給 Azure Kubernetes Service (AKS) 執行個體。
az aks update \
--resource-group <resource-group-name> \
--name <virtual-machine-name> \
--enable-managed-identity
將角色指派給受控識別
接下來,必須授權您建立的受控識別來存取服務匯流排。 作法是將角色指派給受控識別,就像指派給本機開發使用者一樣。
如果您使用服務連接器來連線您的服務,則不需要完成此步驟。 已為您處理必要的設定:
瀏覽至服務匯流排概觀頁面,然後從左側導覽中選取 [存取控制 (IAM)]。
選擇 [新增角色指派]。
在 [角色] 搜尋方塊中,搜尋「Azure 服務匯流排資料擁有者」,此角色常用來管理 Blob 的資料作業。 根據您的使用案例,您可以指派任何適合的角色。 從清單中選取「Azure 服務匯流排資料擁有者」,然後選擇 [下一步]。
在 [新增角色指派] 畫面上,針對 [存取權指派對象為] 選項,選取 [受控識別]。 然後選擇 [+選取成員]。
在飛出視窗中,輸入應用程式服務的名稱來搜尋您建立的受控識別。 選取系統指派的身分識別,然後選擇 [選取] 以關閉飛出視窗功能表。
選取幾次 [下一步],直到能夠選取 [檢閱 + 指派] 來完成角色指派為止。
若要使用 Azure CLI 在資源層級指派角色,您必須先使用 az servicebus show
命令擷取資源識別碼。 您可以使用 --query
參數來篩選輸出屬性。
az servicebus show \
--resource-group '<your-resource-group-name>' \
--name '<your-service-bus-namespace>' \
--query id
複製上述命令的輸出識別碼。 接著,您可以使用 Azure CLI 的 az role
命令來指派角色。
az role assignment create \
--assignee "<your-username>" \
--role "Azure Service Bus Data Owner" \
--scope "<your-resource-id>"
測試應用程式
完成這些程式碼變更之後,在瀏覽器中瀏覽至您的託管應用程式。 您的應用程式應該能夠成功連線到服務匯流排。 請記住,角色指派可能需要幾分鐘才會傳播到整個 Azure 環境。 您的應用程式現在已設定為在本機和實際執行環境中執行,而不需要開發人員管理應用程式本身的秘密。
下一步
在本教學課程中,您已了解如何將應用程式移轉為無密碼連線。