مشاركة عبر


مصادقة الوصول إلى موارد مراكز الأحداث باستخدام Shared Access Signatures.

يمنحك توقيع الوصول المشترك (SAS) تحكما دقيقا في نوع الوصول الذي تمنحه للعملاء. فيما يلي بعض عناصر التحكم التي يمكنك تعيينها في SAS:

  • الفاصل الزمني الذي يكون فيه SAS صالحا، والذي يتضمن وقت البدء ووقت انتهاء الصلاحية.
  • الأذونات الممنوحة من قَِبل SAS. على سبيل المثال، قد تمنح SAS لمساحة اسم مراكز الأحداث إذن الاستماع، ولكن ليس إذن الإرسال.
  • يمكن للعملاء الذين يقدمون بيانات اعتماد صالحة فقط إرسال البيانات إلى event hub.
  • لا يمكن للعميل انتحال شخصية عميل آخر.
  • يمكن منع العميل المحتال من إرسال البيانات إلى مركز الأحداث.

تغطي هذه المقالة مصادقة الوصول إلى موارد مراكز الأحداث باستخدام SAS. لمعرفة المزيد حول تفويض الوصول إلى موارد مراكز الأحداث باستخدام SAS، يُرجى الرجوع إلى هذه المقالة.

إشعار

نوصي باستخدام بيانات اعتماد Microsoft Entra عندما يكون ذلك ممكنا كأفضل ممارسة أمان، بدلا من استخدام توقيعات الوصول المشتركة، والتي يمكن اختراقها بسهولة أكبر. بينما يمكنك الاستمرار في استخدام توقيعات الوصول المشترك (SAS) لمنح وصول دقيق إلى موارد Event Hubs، يوفر معرف Microsoft Entra إمكانات مماثلة دون الحاجة إلى إدارة رموز SAS المميزة أو القلق بشأن إبطال SAS المخترق.

لمزيد من المعلومات حول تكامل Microsoft Entra في Azure Event Hubs، راجع تخويل الوصول إلى مراكز الأحداث باستخدام معرف Microsoft Entra.

تكوين لمصادقة SAS

يمكنك تكوين قاعدة SAS على مساحة اسم مراكز الأحداث أو كيان (مركز الحدث أو موضوع Kafka). تكوين قاعدة SAS على مجموعة مستهلكين غير مدعوم حاليا، ولكن يمكنك استخدام القواعد التي تم تكوينها على مساحة اسم أو كيان لتأمين الوصول إلى مجموعة المستهلكين. توضح الصورة التالية كيفية تطبيق قواعد التخويل على نماذج الكيانات.

رسم تخطيطي يوضح مراكز الأحداث مع قواعد الاستماع والإرسال والإدارة.

في هذا المثال، تحتوي عينة مساحة اسم مراكز الأحداث (ExampleNamespace) على كيانين: eh1 وKafka topic1. يتم تعريف قواعد التخويل على مستوى الكيان وكذلك على مستوى مساحة الاسم.

تنطبق قواعد تخويل manageRuleNS وsendRuleNS و listenRuleNS على كل من eh1 و topic1. تنطبق قواعد التخويل listenRule-eh وsendRule-eh فقط على eh1 وقاعدة تخويل sendRuleT تنطبق فقط على topic1.

عند استخدام قاعدة تخويل sendRuleNS، يمكن إرسال تطبيقات العميل إلى كل من eh1 و topic1. عند استخدام قاعدة تخويل sendRuleT، فإنه يفرض الوصول متعدد المستويات إلى topic1 فقط، وبالتالي لا يمكن لتطبيقات العميل التي تستخدم هذه القاعدة للوصول الآن الإرسال إلى eh1، ولكن فقط إلى topic1.

إنشاء رمز مميز توقيع الوصول المشترك

يمكن لأي عميل لديه حق الوصول إلى اسم قاعدة التخويل وأحد مفاتيح التوقيع الخاصة به إنشاء رمز SAS المميز. يتم إنشاء الرمز المميز بواسطة صياغة سلسلة بالتنسيق التالي:

  • se - لحظة انتهاء صلاحية الرمز المميز. عدد صحيح يعكس الثواني منذ الحقبة 00:00:00 بالتوقيت العالمي المنسق في 1 يناير 1970 (حقبة UNIX) عند انتهاء صلاحية الرمز المميز
  • skn – اسم قاعدة التخويل، وهو اسم مفتاح SAS.
  • sr – URI للموارد التي يتم الوصول إليها.
  • sig – توقيع.

سلسلة التوقيع هي تجزئة SHA-256 المحسوبة عبر URI للمورد (النطاق كما هو موضح في القسم السابق) وتمثيل سلسلة لحظة انتهاء صلاحية الرمز المميز، مفصولة بموجز سطر (LF). يشبه حساب التجزئة التعليمة البرمجية الزائفة التالية ويعيد قيمة تجزئة 256 بت / 32 بايت.

SHA-256('https://<yournamespace>.servicebus.windows.net/'+'\n'+ 1438205742)

يحتوي الرمز المميز على القيم غير المجزأة بحيث يمكن للمستلم إعادة حساب التجزئة باستخدام نفس المعلمات، للتحقق من أن المُصدر يمتلك مفتاح توقيع صالح.

المورد URI هو URI الكامل لمورد ناقل خدمة Microsoft Azure الذي يُطلب الوصول إليه. على سبيل المثال: http://<namespace>.servicebus.windows.net/<entityPath>،sb://<namespace>.servicebus.windows.net/<entityPath>، أو http://contoso.servicebus.windows.net/eh1.

يجب أن يكون عنوان URI مشفرة بنسبة مئوية.

يجب تكوين قاعدة SAS المستخدمة للتوقيع على الكيان المحدد بواسطة URI هذا، أو بواسطة أحد الوالدين الهرميين. على سبيل المثال، http://contoso.servicebus.windows.net/eh1 أو http://contoso.servicebus.windows.net في المثال السابق.

رمز SAS صالح لجميع الموارد مسبوقة بـ <resourceURI> المستخدمة في سلسلة التوقيع.

إشعار

يمكنك إنشاء رمز مميز للوصول لمراكز الأحداث باستخدام نهج الوصول المشترك. لمزيد من المعلومات، يُرجى الرجوع إلى نهج تخويل الوصول المشترك.

إنشاء توقيع (رمز مميز) من السياسة

يوضح القسم التالي إنشاء رمز SAS المميز باستخدام سياسات توقيع الوصول المشترك،

NodeJS

function createSharedAccessToken(uri, saName, saKey) { 
  if (!uri || !saName || !saKey) { 
          throw "Missing required parameter"; 
      } 
  var encoded = encodeURIComponent(uri); 
  var now = new Date(); 
  var week = 60*60*24*7;
  var ttl = Math.round(now.getTime() / 1000) + week;
  var signature = encoded + '\n' + ttl; 
  var hash = crypto.createHmac('sha256', saKey).update(signature, 'utf8').digest('base64'); 
  return 'SharedAccessSignature sr=' + encoded + '&sig=' +  
      encodeURIComponent(hash) + '&se=' + ttl + '&skn=' + saName; 
}

لاستخدام اسم نهج وقيمة مفتاح للاتصال بمركز أحداث، استخدم الدالة الإنشائية EventHubProducerClient التي تأخذ المعلمة AzureNamedKeyCredential.

const producer = new EventHubProducerClient("NAMESPACE NAME.servicebus.windows.net", eventHubName, new AzureNamedKeyCredential("POLICYNAME", "KEYVALUE"));

تحتاج إلى إضافة مرجع إلى AzureNamedKeyCredential.

const { AzureNamedKeyCredential } = require("@azure/core-auth");

لاستخدام رمز SAS المميز الذي قمت بإنشائه باستخدام التعليمات البرمجية، استخدم الدالة EventHubProducerClient الإنشائية التي تأخذ المعلمة AzureSASCredential .

var token = createSharedAccessToken("https://NAMESPACENAME.servicebus.windows.net", "POLICYNAME", "KEYVALUE");
const producer = new EventHubProducerClient("NAMESPACENAME.servicebus.windows.net", eventHubName, new AzureSASCredential(token));

تحتاج إلى إضافة مرجع إلى AzureSASCredential.

const { AzureSASCredential } = require("@azure/core-auth");

JAVA

private static String GetSASToken(String resourceUri, String keyName, String key)
  {
      long epoch = System.currentTimeMillis()/1000L;
      int week = 60*60*24*7;
      String expiry = Long.toString(epoch + week);

      String sasToken = null;
      try {
          String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry;
          String signature = getHMAC256(key, stringToSign);
          sasToken = "SharedAccessSignature sr=" + URLEncoder.encode(resourceUri, "UTF-8") +"&sig=" +
                  URLEncoder.encode(signature, "UTF-8") + "&se=" + expiry + "&skn=" + keyName;
      } catch (UnsupportedEncodingException e) {

          e.printStackTrace();
      }

      return sasToken;
  }


public static String getHMAC256(String key, String input) {
    Mac sha256_HMAC = null;
    String hash = null;
    try {
        sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        Encoder encoder = Base64.getEncoder();

        hash = new String(encoder.encode(sha256_HMAC.doFinal(input.getBytes("UTF-8"))));

    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
   } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return hash;
}

PHP

function generateSasToken($uri, $sasKeyName, $sasKeyValue) 
{ 
    $targetUri = strtolower(rawurlencode(strtolower($uri))); 
    $expires = time(); 	
    $expiresInMins = 60; 
    $week = 60*60*24*7;
    $expires = $expires + $week; 
    $toSign = $targetUri . "\n" . $expires; 
    $signature = rawurlencode(base64_encode(hash_hmac('sha256', 			
     $toSign, $sasKeyValue, TRUE))); 
    
    $token = "SharedAccessSignature sr=" . $targetUri . "&sig=" . $signature . "&se=" . $expires . 		"&skn=" . $sasKeyName; 
    return $token; 
}

C#‎

private static string createToken(string resourceUri, string keyName, string key)
{
    TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
    var week = 60 * 60 * 24 * 7;
    var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + week);
    string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
    using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
    {
        var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
        var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);
        return sasToken;
    }
}

PowerShell

[Reflection.Assembly]::LoadWithPartialName("System.Web")| out-null
$URI="myNamespace.servicebus.windows.net/myEventHub/"
$Access_Policy_Name="RootManageSharedAccessKey"
$Access_Policy_Key="myPrimaryKey"
#Token expires now+300
$Expires=([DateTimeOffset]::Now.ToUnixTimeSeconds())+300
$SignatureString=[System.Web.HttpUtility]::UrlEncode($URI)+ "`n" + [string]$Expires
$HMAC = New-Object System.Security.Cryptography.HMACSHA256
$HMAC.key = [Text.Encoding]::ASCII.GetBytes($Access_Policy_Key)
$Signature = $HMAC.ComputeHash([Text.Encoding]::ASCII.GetBytes($SignatureString))
$Signature = [Convert]::ToBase64String($Signature)
$SASToken = "SharedAccessSignature sr=" + [System.Web.HttpUtility]::UrlEncode($URI) + "&sig=" + [System.Web.HttpUtility]::UrlEncode($Signature) + "&se=" + $Expires + "&skn=" + $Access_Policy_Name
$SASToken

BASH

get_sas_token() {
    local EVENTHUB_URI='EVENTHUBURI'
    local SHARED_ACCESS_KEY_NAME='SHAREDACCESSKEYNAME'
    local SHARED_ACCESS_KEY='SHAREDACCESSKEYVALUE'
    local EXPIRY=${EXPIRY:=$((60 * 60 * 24))} # Default token expiry is 1 day

    local ENCODED_URI=$(echo -n $EVENTHUB_URI | jq -s -R -r @uri)
    local TTL=$(($(date +%s) + $EXPIRY))
    local UTF8_SIGNATURE=$(printf "%s\n%s" $ENCODED_URI $TTL | iconv -t utf8)

    local HASH=$(echo -n "$UTF8_SIGNATURE" | openssl sha256 -hmac $SHARED_ACCESS_KEY -binary | base64)
    local ENCODED_HASH=$(echo -n $HASH | jq -s -R -r @uri)

    echo -n "SharedAccessSignature sr=$ENCODED_URI&sig=$ENCODED_HASH&se=$TTL&skn=$SHARED_ACCESS_KEY_NAME"
}

مصادقة ناشري مراكز الأحداث باستخدام SAS

يعرّف ناشر الحدث نقطة نهاية افتراضية لـ event hub. يمكن استخدام الناشر فقط لإرسال رسائل إلى لوحة وصل حدث وعدم تلقي الرسائل.

عادة، تستخدم لوحة وصل الأحداث ناشر واحد لكل عميل. تُدرج جميع الرسائل التي يتم إرسالها إلى أي من ناشري لوحة وصل حدث ضمن لوحة الوصل الحدث. تمكن الناشرين التحكم في الوصول الدقيق.

يتم تعيين رمز مميز فريد لكل عميل مراكز الأحداث، والذي يتم تحميله إلى العميل. يتم إنتاج الرموز المميزة بحيث يمنح كل رمز مميز حق الوصول إلى ناشر فريد مختلف. يمكن إرسال عميل يحمل الرمز المميز إلى ناشر واحد فقط، ولا يوجد ناشر آخر. إذا كان عملاء متعددة مشاركة نفس الرمز المميز، ثم كل واحد منهم يشارك الناشر.

يتم تخصيص جميع الرموز المميزة بمفاتيح SAS. بشكل عام، يتم توقيع جميع الرموز المميزة مع نفس المفتاح. العملاء ليسوا على علم بالمفتاح، الذي يمنع العملاء من تصنيع الرموز المميزة. العملاء تعمل على نفس الرموز حتى تنتهي صلاحيتها.

على سبيل المثال، لتعريف قواعد التفويض التي تم تحديد نطاقها حتى الإرسال/النشر فقط إلى مراكز الأحداث، يلزمك تحديد قاعدة تفويض الإرسال. يمكن القيام بذلك على مستوى مساحة الاسم أو إعطاء نطاق أكثر دقة إلى كيان معين (مثيل مراكز الأحداث أو موضوع). يُطلق على العميل أو التطبيق الذي تم تحديد نطاقه باستخدام هذا الوصول الدقيق، ناشر مراكز الأحداث. للقيام بذلك، اتبع الخطوات التالية:

  1. أنشئ مفتاح SAS على الكيان الذي تريد نشره لتعيين نطاق الإرسال عليه. لمزيد من المعلومات، يُرجى الرجوع إلى سياسات ترخيص الوصول المشترك.

  2. أنشئ رمزاً مميزاً لـ SAS مع وقت انتهاء صلاحية ناشر معين باستخدام المفتاح الذي تم إنشاؤه في الخطوة 1. للحصول على نموذج التعليمات البرمجية، راجع إنشاء توقيع (رمز مميز) من نهج.

  3. قم بتوفير الرمز المميز لعميل الناشر، والذي يمكنه فقط إرسال إلى الكيان والناشر الذي يمنح الرمز المميز حق الوصول إليه.

    بمجرد انتهاء صلاحية الرمز المميز، يفقد العميل إمكانية الوصول إلى الإرسال/النشر إلى الكيان.

إشعار

على الرغم من أننا لا نوصي بذلك، فمن الممكن تزويد الأجهزة بالرموز المميزة التي تمنح الوصول إلى مركز أحداث أو مساحة اسم. يمكن لأي جهاز يحمل هذا الرمز المميز إرسال رسائل مباشرة إلى event hub هذا. علاوة على ذلك، لا يمكن حظر الجهاز من الإرسال إلى لوحة الوصل الحدث.

نوصي بإعطاء نطاقات محددة ومتعددة المستويات.

هام

بمجرد إنشاء الرموز المميزة، يتم تزويد كل عميل برمز فريد خاص به.

عندما يرسل العميل البيانات إلى event hub، فإنه يضع علامة على طلبه بالرمز المميز. لمنع المهاجم من التنصت وسرقة الرمز المميز، يجب أن يتم الاتصال بين العميل ومركز الحدث عبر قناة مشفرة.

إذا سرق أحد المهاجمين رمزاً مميزاً، فيمكن للمهاجم انتحال صفة العميل الذي تمت سرقة رمزه المميز. يؤدي إدراج ناشر في قائمة الحظر إلى جعل هذا العميل غير قابل للاستخدام حتى يتلقى رمزاً جديداً يستخدم ناشراً مختلفاً.

مصادقة مستهلكين مراكز الأحداث باستخدام SAS

لمصادقة التطبيقات الخلفية التي تستهلك من البيانات التي تم إنشاؤها بواسطة منتجي مراكز الأحداث، تتطلب مصادقة الرمز المميز لمراكز الأحداث من عملائها إما الحصول على حقوق الإدارة أو امتيازات الاستماع المعينة لمساحة اسم مراكز الأحداث الخاصة به أو مثيل لوحة وصل الحدث أو الموضوع الخاص به. يتم استهلاك البيانات من مراكز الأحداث باستخدام مجموعات المستهلكين. بينما يمنحك نهج SAS نطاق متعدد المستويات، يتم تعريف هذا النطاق فقط على مستوى الكيان وليس على مستوى المستهلك. وهذا يعني أن الامتيازات المحددة على مستوى مساحة الاسم أو مركز الحدث أو مستوى الموضوع يتم تطبيقها على مجموعات المستهلكين لهذا الكيان.

تعطيل مصادقة مفتاح SAS/المحلي

بالنسبة لمتطلبات أمان تنظيمية معينة، تريد تعطيل مصادقة المفتاح المحلي/SAS بالكامل والاعتماد على المصادقة المستندة إلى معرف Microsoft Entra، وهي الطريقة الموصى بها للاتصال بمراكز الأحداث Azure. يمكنك تعطيل مصادقة مفتاح محلي/SAS على مستوى مساحة الاسم لمراكز الأحدث باستخدام مدخل Azure أو قالب Azure Resource Manager.

تعطيل مصادقة مفتاح SAS/المحلي عبر المدخل

يمكنك تعطيل مصادقة مفتاح محلي/SAS لمساحة اسم مراكز الأحداث معينة باستخدام المدخل Azure.

  1. في مدخل Microsoft Azure، انتقل إلى مساحة اسم Event Hubs.

  2. في صفحة Overview ، حدد Enabled for Local Authentication كما هو موضح في الصورة التالية.

    لقطة شاشة تعرض المصادقة المحلية المحددة.

  3. في النافذة المنبثقة Local Authentication ، حدد Disabled، وحدد OK.

    لقطة شاشة تعرض نافذة المصادقة المحلية المنبثقة مع تحديد الخيار معطل.

تعطيل مصادقة المفتاح المحلي/SAS باستخدام قالب

يمكنك تعطيل المصادقة المحلية لمساحة اسم معينة لمراكز الأحداث عن طريق تعيين disableLocalAuth الخاصية إلى true كما هو موضح في قالب Azure Resource Manager التالي (قالب ARM).

"resources":[
      {
         "apiVersion":"[variables('ehVersion')]",
         "name":"[parameters('eventHubNamespaceName')]",
         "type":"Microsoft.EventHub/Namespaces",
         "location":"[variables('location')]",
         "sku":{
            "name":"Standard",
            "tier":"Standard"
         },
         "resources": [
    {
      "apiVersion": "2017-04-01",
      "name": "[parameters('eventHubNamespaceName')]",
      "type": "Microsoft.EventHub/Namespaces",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard"
      },
      "properties": {
        "isAutoInflateEnabled": "true",
        "maximumThroughputUnits": "7", 
        "disableLocalAuth": true
      },
      "resources": [
        {
          "apiVersion": "2017-04-01",
          "name": "[parameters('eventHubName')]",
          "type": "EventHubs",
          "dependsOn": [
            "[concat('Microsoft.EventHub/namespaces/', parameters('eventHubNamespaceName'))]"
          ],
          "properties": {
            "messageRetentionInDays": "[parameters('messageRetentionInDays')]",
            "partitionCount": "[parameters('partitionCount')]"
          }

        }
      ]
    }
  ]

العينات

  • راجع نموذج .NET #6 في موقع GitHub هذا لمعرفة كيفية نشر الأحداث إلى مركز أحداث باستخدام بيانات اعتماد الوصول المشتركة أو هوية بيانات اعتماد Azure الافتراضية.
  • راجع نموذج .NET #5 في موقع GitHub هذا لمعرفة كيفية استهلاك الأحداث أو معالجتها باستخدام بيانات اعتماد الوصول المشترك أو هوية بيانات اعتماد Azure الافتراضية.

الخطوات التالية

راجع المقالات التالية:

راجع المقالات التالية ذات الصلة: