使用共用存取簽章 服務匯流排 訪問控制

本文討論共用存取簽章(SAS)、其運作方式,以及如何以與 Azure 服務匯流排 無關的平臺方式加以使用。

SAS 會根據在命名空間或傳訊實體(佇列或主題)上設定的授權規則,保護 服務匯流排 的存取權。 授權規則具有名稱、與特定許可權相關聯,並攜帶一組密碼編譯密鑰。 您可以使用規則的名稱和金鑰,透過 服務匯流排 SDK 或在您自己的程式代碼中產生 SAS 令牌。 然後,用戶端可以將令牌傳遞至 服務匯流排,以證明要求作業的授權。

注意

Azure 服務匯流排 支援使用 Microsoft Entra ID 來授權存取 服務匯流排 命名空間及其實體。 使用 Microsoft Entra ID 所傳回的 OAuth 2.0 令牌授權使用者或應用程式,可提供優於共用存取簽章 (SAS) 的優越安全性和易於使用性。 使用 Microsoft Entra 識別碼,就不需要將令牌儲存在您的程式代碼中,並風險潛在的安全性弱點。

Microsoft 建議您盡可能將 Microsoft Entra 識別碼與 Azure 服務匯流排 應用程式搭配使用。 如需詳細資訊,請參閱下列文章:

您可以停用 服務匯流排 命名空間的本機或 SAS 金鑰驗證,只允許 Microsoft Entra 驗證。 如需逐步指示,請參閱 停用本機驗證

SAS 概觀

共用存取簽章是使用簡單令牌的宣告型授權機制。 當您使用 SAS 時,永遠不會在線路上傳遞金鑰。 密鑰可用來以密碼編譯方式簽署服務稍後可驗證的資訊。 SAS 可以類似於使用者名稱和密碼配置,其中用戶端直接擁有授權規則名稱和相符密鑰。 SAS 也可用於類似同盟安全性模型,其中用戶端會從安全性令牌服務收到限時且已簽署的存取令牌,而不需要擁有簽署密鑰。

服務匯流排 中的 SAS 驗證會設定為具有相關聯訪問許可權的具名共用存取授權原則,以及一對主要和次要密碼編譯密鑰。 索引鍵是Base 64表示法中的256位值。 您可以在命名空間層級、服務匯流排 佇列主題上設定規則。

注意

這些索引鍵是使用Base 64表示法的純文字字串,而且在使用前不得譯碼。

共用存取簽章令牌包含所選授權原則的名稱、應存取的資源 URI、到期立即,以及使用這些字段計算的 HMAC-SHA256 密碼編譯簽章,這些字段會使用所選授權規則的主要或次要密碼編譯密鑰。

共用存取授權原則

每個 服務匯流排 命名空間和每個 服務匯流排 實體都有由規則組成的共用存取授權原則。 命名空間層級的原則會套用至命名空間中的所有實體,而不論其個別原則設定為何。

針對每個授權原則規則,您決定三項資訊: 名稱範圍許可權。 名稱只是該名稱;在該範圍內的唯一名稱。 範圍足夠簡單:這是有問題的資源的URI。 對於 服務匯流排 命名空間,範圍是完整的命名空間,例如 https://<yournamespace>.servicebus.windows.net/

原則規則賦予的許可權可以是下列各項的組合:

  • 傳送 - 授與將訊息傳送至實體的許可權
  • 接聽 - 授與接收權(佇列、訂用帳戶)和所有相關訊息處理的許可權
  • 管理 - 授與管理命名空間拓撲的許可權,包括建立和刪除實體

[ 管理 ] 許可權包含 [傳送] 和 [接聽] 許可權。

命名空間或實體原則最多可保留 12 個共用存取授權規則,提供三組規則的空間,每個規則涵蓋基本許可權,以及傳送和接聽的組合。 此限制是每個實體,這表示命名空間和每個實體最多可以有12個共用存取授權規則。 此限制會強調 SAS 原則存放區不是用戶或服務帳戶存放區。 如果您的應用程式需要根據使用者或服務身分識別授與對 服務匯流排 的存取權,它應該實作在驗證和存取檢查之後發出 SAS 令牌的安全性令牌服務。

授權規則會 指派主鍵次要金鑰。 這些金鑰是密碼編譯強金鑰。 不要失去或洩露它們 - 它們一律可在 Azure 入口網站 中使用。 您可以使用其中一個產生的金鑰,而且您可以隨時重新產生它們。 如果您在原則中重新產生或變更密鑰,則根據該金鑰的所有先前發行的令牌都會立即失效。 不過,根據這類令牌建立的持續聯機會繼續運作,直到令牌到期為止。

當您建立 服務匯流排 命名空間時,系統會自動為命名空間建立名為 RootManageSharedAccessKey 的原則規則。 此原則具有整個命名空間的管理許可權。 建議您將此規則視為系統管理 帳戶,且不要在應用程式中使用它。 您可以透過PowerShell或 Azure CLI,在 入口網站中命名空間的 [共用存取原則 ] 索引標籤中建立更多原則規則。

建議您定期重新產生 SharedAccessAuthorizationRule 物件中使用的密鑰。 主要和次要金鑰位置存在,以便您可以逐漸輪替密鑰。 如果您的應用程式通常會使用主鍵,您可以將主鍵複製到次要密鑰位置,然後才重新產生主鍵。 然後,可以將新的主鍵值設定為用戶端應用程式,而用戶端應用程式會使用次要位置中的舊主鍵繼續存取。 更新所有客戶端之後,您就可以重新產生次要密鑰,最後淘汰舊的主鍵。

如果您知道或懷疑密鑰遭到入侵,而且您必須撤銷金鑰,您可以重新產生 SharedAccessAuthorizationRulePrimaryKey 和 SecondaryKey,並以新的密鑰取代它們。 此程式會使所有以舊金鑰簽署的令牌失效。

使用 SAS 時的最佳做法

當您在應用程式中使用共用存取簽章時,必須注意兩個潛在的風險:

  • 如果 SAS 洩漏,則任何取得 SAS 的人員都可以使用它,這可能會危害您的 服務匯流排 資源。
  • 如果提供給用戶端應用程式的SAS過期,且應用程式無法從服務擷取新的SAS,則應用程式的功能可能會受到阻礙。

使用共用存取簽章的下列建議有助於降低這些風險:

  • 讓用戶端在必要時自動更新 SAS:客戶端應該在到期前更新 SAS,以便在提供 SAS 的服務無法使用時允許重試的時間。 如果您的 SAS 是要用於一些短期的短期作業,預期會在到期期間內完成,則可能不必要,因為不會更新 SAS。 不過,如果您有透過 SAS 定期提出要求的用戶端,則到期的可能性就會生效。 關鍵考慮是平衡 SAS 短期(如先前所述)的需求與確保用戶端要求更新足夠早的需求(以避免因為 SAS 在成功續約之前到期而中斷)。
  • 請小心 SAS 開始時間:如果您將 SAS 的開始時間設定為 現在,則由於時鐘扭曲(根據不同機器的目前時間差異),您可能會在前幾分鐘間歇看到失敗。 一般而言,將開始時間設定為過去至少 15 分鐘。 或者,完全不要設定它,這會在所有情況下立即生效。 同樣也適用於到期時間。 請記住,您可能會在任何要求上觀察到最多 15 分鐘的時鐘誤差方向。
  • 要存取的資源特定:安全性最佳做法是為使用者提供最低必要許可權。 如果使用者只須要針對單一實體的讀取存取權,請為該單一實體授予讀取存取權限,無須為所有實體授予讀取/寫入/刪除權限。 如果 SAS 遭到入侵,它也有助於降低損害,因為 SAS 在攻擊者手中擁有較少的權力。
  • 請勿一律使用SAS:有時針對您的 服務匯流排 與特定作業相關聯的風險超過 SAS 的優點。 針對這類作業,請建立中介層服務,以在商務規則驗證、驗證和稽核之後寫入您的 服務匯流排。
  • 一律使用 HTTP:一律使用 Https 來建立或散發 SAS。 如果 SAS 透過 HTTP 傳遞並遭到攔截,執行中間人鏈接的攻擊者就能夠讀取 SAS,然後使用它就像預期使用者可能擁有的一樣,可能會危害敏感數據,或允許惡意使用者損毀數據。

共用存取簽章驗證的設定

您可以在 服務匯流排 命名空間、佇列或主題上設定共用存取授權原則。 目前不支援在 服務匯流排 訂用帳戶上設定它,但您可以使用在命名空間或主題上設定的規則來保護訂用帳戶的存取。

Diagram that shows an example namespace with a few authorization rules.

在此圖中,manageRuleNS、sendRuleNS 和 listenRuleNS 授權規則同時套用至佇列 Q1 和 topic T1,而 listenRuleQ 和 sendRuleQ 僅適用於佇列 Q1,而 sendRuleT 僅適用於主題 T1。

產生共用存取簽章令牌

任何有權存取授權規則名稱及其簽署密鑰的用戶端,都可以產生SAS令牌。 令牌是透過以下列格式製作字串所產生:

SharedAccessSignature sig=<signature-string>&se=<expiry>&skn=<keyName>&sr=<URL-encoded-resourceURI>
  • se - 令牌立即到期。 整數會反映自 1970 年 1 月 1 日 Epoch 00:00:00 UTC (UNIX epoch) 令牌到期後的秒數。

  • skn - 授權規則的名稱。

  • sr - 所存取資源的 URL 編碼 URI。

  • sig - URL 編碼HMACSHA256簽章。 哈希計算看起來類似下列虛擬程式碼,並傳回原始二進位輸出的base64。

    urlencode(base64(hmacsha256(urlencode('https://<yournamespace>.servicebus.windows.net/') + "\n" + '<expiry instant>', '<signing key>')))
    

重要

如需使用不同程式設計語言產生 SAS 令牌的範例,請參閱 產生 SAS 令牌

令牌包含非哈希值,讓收件者可以使用相同的參數重新計算哈希,確認簽發者是否擁有有效的簽署密鑰。

資源 URI 是宣告存取權之 服務匯流排 資源的完整 URI。 例如,或 sb://<namespace>.servicebus.windows.net/<entityPath>http://<namespace>.servicebus.windows.net/<entityPath>也就是 http://contoso.servicebus.windows.net/contosoTopics/T1/Subscriptions/S3

URI 必須經過 百分比編碼

用於簽署的共用存取授權規則必須在此 URI 所指定的實體上設定,或由其中一個階層式父代設定。 例如, http://contoso.servicebus.windows.net/contosoTopics/T1 或在 http://contoso.servicebus.windows.net 上一個範例中。

SAS 令牌對於前面加上 <resourceURI> 中所 signature-string使用 的所有資源而言都是有效的。

重新產生金鑰

建議您定期重新產生共用存取授權原則中使用的金鑰。 主要和次要金鑰位置存在,以便您可以逐漸輪替密鑰。 如果您的應用程式通常會使用主鍵,您可以將主鍵複製到次要密鑰位置,然後才重新產生主鍵。 然後,可以將新的主鍵值設定為用戶端應用程式,而用戶端應用程式會使用次要位置中的舊主鍵繼續存取。 更新所有客戶端之後,您就可以重新產生次要密鑰,最後淘汰舊的主鍵。

如果您知道或懷疑金鑰遭到入侵,而且您必須撤銷金鑰,您可以重新產生共用存取授權原則的主鍵和次要金鑰,並以新的金鑰取代金鑰。 此程式會使所有以舊金鑰簽署的令牌失效。

若要在 Azure 入口網站重新產生主要和次要金鑰,請遵循下列步驟:

  1. 流覽至 Azure 入口網站中的 服務匯流排 命名空間。

  2. 選取 左側功能表上的 [共用存取原則 ]。

  3. 從清單中選取原則。 在下列範例中, 已選取 RootManageSharedAccessKey

  4. 若要重新產生主鍵,請在 [SAS 原則:RootManageSharedAccessKey ] 頁面上,選取 命令行上的 [重新產生主鍵 ]。

    Screenshot that shows how to regenerate a primary key.

  5. 若要重新產生次要密鑰,請在 [SAS 原則:RootManageSharedAccessKey ] 頁面上,從命令行選取 ... ,然後選取 [ 重新產生次要密鑰]。

    Screenshot of SAS Policy page with Regenerate options selected.

如果您使用 Azure PowerShell,請使用 New-AzServiceBusKey Cmdlet 來重新產生 服務匯流排 命名空間的主要和次要密鑰。 您也可以使用 -KeyValue 參數來指定所產生之主要和次要金鑰的值。

如果您使用 Azure CLI,請使用 az servicebus namespace authorization-rule keys renew 命令來重新產生 服務匯流排 命名空間的主要和次要密鑰。 您也可以使用 --key-value 參數來指定所產生之主要和次要金鑰的值。

使用 服務匯流排 共用存取簽章驗證

以下所述的案例包括設定授權規則、產生SAS令牌和客戶端授權。

如需說明設定和使用SAS授權之 服務匯流排 應用程式的範例,請參閱使用 服務匯流排 共用存取簽章驗證。

存取實體上的共用存取授權規則

在管理連結庫的佇列或主題上使用 get/update 作業,服務匯流排 存取/更新對應的共用存取授權規則。 您也可以使用這些連結庫建立佇列或主題時新增規則。

使用共用存取簽章授權

在任何正式支援的語言中使用任何 服務匯流排 SDK 的應用程式,例如 .NET、Java、JavaScript 和 Python,都可以透過傳遞至用戶端建構函式的 連接字串 來使用 SAS 授權。

連線 ion 字串可以包含規則名稱 (SharedAccessKeyName) 和規則密鑰 (SharedAccessKey) 或先前發行的令牌 (SharedAccessSignature)。 當這些存在於 連接字串 傳遞至接受 連接字串 的任何建構函式或 Factory 方法時,會自動建立並填入 SAS 令牌提供者。

若要搭配 服務匯流排 訂用帳戶使用 SAS 授權,您可以使用 服務匯流排 命名空間或主題上設定的 SAS 金鑰。

使用共用存取簽章 (於 HTTP 層級)

既然您已瞭解如何為 服務匯流排 中的任何實體建立共用存取簽章,您即可執行 HTTP POST:

POST https://<yournamespace>.servicebus.windows.net/<yourentity>/messages
Content-Type: application/json
Authorization: SharedAccessSignature sr=https%3A%2F%2F<yournamespace>.servicebus.windows.net%2F<yourentity>&sig=<yoursignature from code above>&se=1438205742&skn=KeyName
ContentType: application/atom+xml;type=entry;charset=utf-8

請記住,這適用於所有專案。 您可以建立佇列、主題或訂用帳戶的 SAS。

如果您為傳送者或用戶端提供 SAS 令牌,則他們沒有密鑰,而且無法反轉哈希以取得它。 因此,您可以控制其可存取的內容,以及存取時間長度。 請務必記住,如果您在原則中變更主鍵,則從原則建立的任何共用存取簽章都會失效。

使用共用存取簽章 (於 AMQP 層級)

在上一節中,您已瞭解如何將 SAS 令牌與 HTTP POST 要求搭配使用,以將數據傳送至 服務匯流排。 如您所瞭解,您可以在許多案例中使用慣用通訊協議的進階消息佇列通訊協定(AMQP)來存取 服務匯流排。 AMQP 的 SAS 令牌使用方式描述於 自 2013 年以來的工作草稿中 AMQP 宣告式安全性 1.0 版,但目前由 Azure 支援。

開始將數據傳送至 服務匯流排 之前,發行者必須將AMQP訊息內的SAS令牌傳送至名為 $cbs妥善定義的AMQP節點(您可以看到它是服務用來取得和驗證所有 SAS 令牌的「特殊」佇列)。 發行者必須在AMQP訊息內指定 ReplyTo 欄位;它是服務以令牌驗證結果回復發行者的節點(發行者與服務之間的簡單要求/回復模式)。 此回復節點會「即時」建立,並說明「動態建立遠端節點」,如AMQP 1.0規格所述。 檢查 SAS 令牌是否有效之後,發行者就可以繼續並開始將數據傳送至服務。

下列步驟示範如何使用 AMQP.NET Lite 連結庫,使用 AMQP 通訊協定傳送 SAS 令牌。 如果您無法使用以 C# 開發的正式 服務匯流排 SDK(例如,在 WinRT、.NET Compact Framework、.NET Micro Framework 和 Mono 上)。它很有用。 此連結庫有助於瞭解宣告型安全性在AMQP層級的運作方式,因為您已瞭解它在 HTTP 層級的運作方式(HTTP POST 要求和在「授權」標頭內傳送的SAS令牌。 如果您不需要對AMQP有如此深入的知識,您可以使用任何支持的語言,例如 .NET、Java、JavaScript、Python 和 Go 的官方 服務匯流排 SDK,這會為您執行此動作。

C#

/// <summary>
/// Send claim-based security (CBS) token
/// </summary>
/// <param name="shareAccessSignature">Shared access signature (token) to send</param>
private bool PutCbsToken(Connection connection, string sasToken)
{
    bool result = true;
    Session session = new Session(connection);

    string cbsClientAddress = "cbs-client-reply-to";
    var cbsSender = new SenderLink(session, "cbs-sender", "$cbs");
    var cbsReceiver = new ReceiverLink(session, cbsClientAddress, "$cbs");

    // construct the put-token message
    var request = new Message(sasToken);
    request.Properties = new Properties();
    request.Properties.MessageId = Guid.NewGuid().ToString();
    request.Properties.ReplyTo = cbsClientAddress;
    request.ApplicationProperties = new ApplicationProperties();
    request.ApplicationProperties["operation"] = "put-token";
    request.ApplicationProperties["type"] = "servicebus.windows.net:sastoken";
    request.ApplicationProperties["name"] = Fx.Format("amqp://{0}/{1}", sbNamespace, entity);
    cbsSender.Send(request);

    // receive the response
    var response = cbsReceiver.Receive();
    if (response == null || response.Properties == null || response.ApplicationProperties == null)
    {
        result = false;
    }
    else
    {
        int statusCode = (int)response.ApplicationProperties["status-code"];
        if (statusCode != (int)HttpStatusCode.Accepted && statusCode != (int)HttpStatusCode.OK)
        {
            result = false;
        }
    }

    // the sender/receiver might be kept open for refreshing tokens
    cbsSender.Close();
    cbsReceiver.Close();
    session.Close();

    return result;
}

方法PutCbsToken()接收連接 (AMQP 連接類別實例,如 AMQP .NET Lite 連結庫所提供),代表服務的 TCP 連線,以及 SAS 令牌要傳送的 sasToken 參數。

注意

請務必使用 SASL 驗證機制設定為 ANONYMOUS 來建立連線(而不是當您不需要傳送 SAS 令牌時所使用的使用者名稱和密碼的預設 PLAIN)。

接下來,發行者會建立兩個AMQP連結,以傳送SAS令牌,並從服務接收回復(令牌驗證結果)。

AMQP 訊息包含一組屬性,以及比簡單訊息更多的資訊。 SAS 令牌是訊息主體(使用其建構函式)。 “ ReplyTo” 屬性會設定為節點名稱,以便接收接收者連結上的驗證結果(您可以視需要變更其名稱,而且服務會動態建立它)。 服務會使用最後三個應用程式/自定義屬性來指出它必須執行的作業類型。 如 CBS 草稿規格所述,它們必須是 作業名稱 (“put-token”), 令牌 類型(在此案例中為 a servicebus.windows.net:sastoken),以及 令牌套用物件之「名稱」 (整個實體)。

發行者在傳送者連結上的 SAS 令牌之後,發行者必須在接收者連結上讀取回復。 回復是簡單的AMQP訊息,具有名為 「status-code」 的應用程式屬性,可以包含與 HTTP 狀態代碼相同的值。

服務匯流排 作業所需的許可權

下表顯示 服務匯流排 資源上各種作業所需的訪問許可權。

作業 需要宣告 宣告範圍
Namespace
在命名空間上設定授權規則 管理 任何命名空間位址
服務登錄
列舉私人原則 管理 任何命名空間位址
開始接聽命名空間 接聽 任何命名空間位址
將訊息傳送至命名空間的接聽程式 傳送 任何命名空間位址
佇列
建立佇列 管理 任何命名空間位址
刪除佇列 管理 任何有效的佇列位址
列舉佇列 管理 /$Resources/佇列
取得佇列描述 管理 任何有效的佇列位址
設定佇列的授權規則 管理 任何有效的佇列位址
傳送至佇列 傳送 任何有效的佇列位址
從佇列接收訊息 接聽 任何有效的佇列位址
在以窺視鎖定模式接收訊息之後放棄或完成訊息 接聽 任何有效的佇列位址
延遲訊息以供稍後擷取 接聽 任何有效的佇列位址
將訊息失效 接聽 任何有效的佇列位址
取得與消息佇列會話相關聯的狀態 接聽 任何有效的佇列位址
設定與消息佇列會話相關聯的狀態 接聽 任何有效的佇列位址
排程訊息以供稍後傳遞 接聽 任何有效的佇列位址
主題
建立主題 管理 任何命名空間位址
刪除主題 管理 任何有效的主題位址
列舉主題 管理 /$Resources/Topics
取得主題描述 管理 任何有效的主題位址
設定主題的授權規則 管理 任何有效的主題位址
傳送至主題 傳送 任何有效的主題位址
訂用帳戶
建立訂用帳戶 管理 任何命名空間位址
刪除訂用帳戶 管理 ../myTopic/Subscriptions/mySubscription
列舉訂用帳戶 管理 ../myTopic/Subscriptions
取得訂用帳戶描述 管理 ../myTopic/Subscriptions/mySubscription
在以窺視鎖定模式接收訊息之後放棄或完成訊息 接聽 ../myTopic/Subscriptions/mySubscription
延遲訊息以供稍後擷取 接聽 ../myTopic/Subscriptions/mySubscription
將訊息失效 接聽 ../myTopic/Subscriptions/mySubscription
取得與主題會話相關聯的狀態 接聽 ../myTopic/Subscriptions/mySubscription
設定與主題會話相關聯的狀態 接聽 ../myTopic/Subscriptions/mySubscription
規則
建立規則 接聽 ../myTopic/Subscriptions/mySubscription
刪除規則 接聽 ../myTopic/Subscriptions/mySubscription
列舉規則 管理或接聽 ../myTopic/Subscriptions/mySubscription/Rules

下一步

若要深入瞭解 服務匯流排 傳訊,請參閱下列主題。