Uwierzytelnianie dostępu do zasobów usługi Event Hubs przy użyciu sygnatur dostępu współdzielonego (SAS)

Sygnatura dostępu współdzielonego (SAS) zapewnia szczegółową kontrolę nad typem dostępu udzielanego klientom. Oto niektóre kontrolki, które można ustawić w sygnaturze dostępu współdzielonego:

  • Interwał, dla którego sygnatura dostępu współdzielonego jest prawidłowa, w tym czas rozpoczęcia i czas wygaśnięcia.
  • Uprawnienia przyznane przez sygnaturę dostępu współdzielonego. Na przykład sygnatura dostępu współdzielonego dla przestrzeni nazw usługi Event Hubs może przyznać uprawnienie nasłuchiwania, ale nie uprawnienie do wysyłania.
  • Tylko klienci, którzy prezentują prawidłowe poświadczenia, mogą wysyłać dane do centrum zdarzeń.
  • Klient nie może personifikować innego klienta.
  • Nieautoryzowy klient może mieć zablokowaną możliwość wysyłania danych do centrum zdarzeń.

W tym artykule opisano uwierzytelnianie dostępu do zasobów usługi Event Hubs przy użyciu sygnatury dostępu współdzielonego. Aby dowiedzieć się więcej na temat autoryzowania dostępu do zasobów usługi Event Hubs przy użyciu sygnatury dostępu współdzielonego, zobacz ten artykuł.

Uwaga

Firma Microsoft zaleca używanie poświadczeń firmy Microsoft entra, jeśli jest to możliwe jako najlepsze rozwiązanie w zakresie zabezpieczeń, zamiast używania sygnatur dostępu współdzielonego, co może być łatwiejsze w przypadku naruszenia zabezpieczeń. Mimo że można nadal używać sygnatur dostępu współdzielonego (SAS), aby udzielić szczegółowego dostępu do zasobów usługi Event Hubs, identyfikator Entra firmy Microsoft oferuje podobne możliwości bez konieczności zarządzania tokenami SAS lub martwienia się o odwołanie naruszonej sygnatury dostępu współdzielonego.

Aby uzyskać więcej informacji na temat integracji z usługą Microsoft Entra w usłudze Azure Event Hubs, zobacz Autoryzowanie dostępu do usługi Event Hubs przy użyciu identyfikatora Entra firmy Microsoft.

Konfigurowanie uwierzytelniania sygnatury dostępu współdzielonego

Regułę sygnatury dostępu współdzielonego można skonfigurować w przestrzeni nazw usługi Event Hubs lub jednostce (wystąpieniu centrum zdarzeń lub temacie platformy Kafka w centrum zdarzeń). Konfigurowanie reguły sygnatury dostępu współdzielonego dla grupy odbiorców nie jest obecnie obsługiwane, ale można użyć reguł skonfigurowanych w przestrzeni nazw lub jednostce w celu zabezpieczenia dostępu do grupy odbiorców.

Na poniższej ilustracji przedstawiono sposób stosowania reguł autoryzacji dla przykładowych jednostek.

Konfigurowanie reguły autoryzacji

W tym przykładzie przykładowa przestrzeń nazw usługi Event Hubs (ExampleNamespace) ma dwie jednostki: eh1 i kafka topic1. Reguły autoryzacji są definiowane zarówno na poziomie jednostki, jak i na poziomie przestrzeni nazw.

Reguły autoryzacji manageRuleNS, sendRuleNS i listenRuleNS dotyczą zarówno reguł autoryzacji eh1, jak i t1. Reguły autoryzacji listenRule-eh i sendRule-eh mają zastosowanie tylko do reguły autoryzacji eh1 i sendRuleT dotyczy tylko tematu1.

W przypadku korzystania z reguły autoryzacji sendRuleNS aplikacje klienckie mogą wysyłać zarówno do eh1, jak i topic1. Gdy jest używana reguła autoryzacji sendRuleT, wymusza ona szczegółowy dostęp tylko do tematu1, dlatego aplikacje klienckie korzystające z tej reguły na potrzeby dostępu nie mogą teraz wysyłać do eh1, ale tylko do tematu1.

Generowanie tokenu sygnatury dostępu współdzielonego

Każdy klient z dostępem do nazwy reguły autoryzacji i jeden z jego kluczy podpisywania może wygenerować token SAS. Token jest generowany przez utworzenie ciągu w następującym formacie:

  • se — Natychmiastowe wygaśnięcie tokenu. Liczba całkowita odzwierciedlająca sekundy od epoki 00:00:00 UTC 1 stycznia 1970 r. (system UNIX epoki) po wygaśnięciu tokenu
  • skn — nazwa reguły autoryzacji, która jest nazwą klucza sygnatury dostępu współdzielonego.
  • sr — identyfikator URI zasobu, do których uzyskuje się dostęp.
  • sig –Podpis.

Ciąg podpisu to skrót SHA-256 obliczony za pośrednictwem identyfikatora URI zasobu (zakres opisany w poprzedniej sekcji) i ciąg reprezentujący natychmiastowe wygaśnięcie tokenu oddzielony przez crLF. Obliczenie skrótu wygląda podobnie do poniższego pseudo kodu i zwraca wartość skrótu 256-bitowego/32-bajtowego.

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

Token zawiera wartości inne niż skróty, aby odbiorca mógł ponownie skompilować skrót z tymi samymi parametrami, sprawdzając, czy wystawca jest w posiadaniu prawidłowego klucza podpisywania.

Identyfikator URI zasobu to pełny identyfikator URI zasobu usługi Service Bus, do którego jest uzyskiwany dostęp. Na przykład lub http://<namespace>.servicebus.windows.net/<entityPath>sb://<namespace>.servicebus.windows.net/<entityPath> to znaczy http://contoso.servicebus.windows.net/eh1.

Identyfikator URI musi być zakodowany procentowo.

Reguła sygnatury dostępu współdzielonego używana do podpisywania musi być skonfigurowana w jednostce określonej przez ten identyfikator URI lub przez jeden z jego hierarchicznych elementów nadrzędnych. Na przykład http://contoso.servicebus.windows.net/eh1 lub http://contoso.servicebus.windows.net w poprzednim przykładzie.

Token SAS jest prawidłowy dla wszystkich zasobów poprzedzonych prefiksem <resourceURI> używanym w ciągu podpisu.

Uwaga

Token dostępu dla usługi Event Hubs jest generowany przy użyciu zasad dostępu współdzielonego. Aby uzyskać więcej informacji, zobacz Zasady autoryzacji dostępu współdzielonego.

Generowanie sygnatury (tokenu) na podstawie zasad

W poniższej sekcji przedstawiono generowanie tokenu SAS przy użyciu zasad sygnatury dostępu współdzielonego,

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

Aby użyć nazwy zasad i wartości klucza w celu nawiązania połączenia z centrum zdarzeń, użyj konstruktora EventHubProducerClientAzureNamedKeyCredential , który przyjmuje parametr .

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

Musisz dodać odwołanie do AzureNamedKeyCredentialelementu .

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

Aby użyć tokenu SAS wygenerowanego przy użyciu kodu, użyj EventHubProducerClient konstruktora AzureSASCredential , który przyjmuje parametr .

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

Musisz dodać odwołanie do AzureSASCredentialelementu .

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"
}

Uwierzytelnianie wydawców usługi Event Hubs przy użyciu sygnatury dostępu współdzielonego

Wydawca zdarzeń definiuje wirtualny punkt końcowy dla centrum zdarzeń. Wydawca może służyć tylko do wysyłania komunikatów do centrum zdarzeń i nie odbierać komunikatów.

Zazwyczaj centrum zdarzeń zatrudnia jednego wydawcę na klienta. Wszystkie komunikaty wysyłane do dowolnego wydawcy centrum zdarzeń są w kolejce w tym centrum zdarzeń. Wydawcy umożliwiają szczegółową kontrolę dostępu.

Każdy klient usługi Event Hubs ma przypisany unikatowy token, który jest przekazywany do klienta. Tokeny są tworzone tak, aby każdy unikatowy token udzielał dostępu do innego unikatowego wydawcy. Klient, który zawiera token, może wysyłać tylko do jednego wydawcy, a żaden inny wydawca. Jeśli wielu klientów współużytkuje ten sam token, każdy z nich współużytkuje wydawcę.

Wszystkie tokeny są przypisywane przy użyciu kluczy SAS. Zazwyczaj wszystkie tokeny są podpisane przy użyciu tego samego klucza. Klienci nie wiedzą o kluczu, co uniemożliwia klientom korzystanie z tokenów produkcyjnych. Klienci działają na tych samych tokenach, dopóki nie wygasną.

Aby na przykład zdefiniować reguły autoryzacji ograniczone do wysyłania/publikowania tylko do usługi Event Hubs, należy zdefiniować regułę autoryzacji wysyłania. Można to zrobić na poziomie przestrzeni nazw lub dać bardziej szczegółowy zakres konkretnej jednostki (wystąpienie usługi Event Hubs lub temat). Klient lub aplikacja, która ma zakres z takim szczegółowym dostępem, jest nazywana wydawcą usługi Event Hubs. W tym celu wykonaj następujące kroki:

  1. Utwórz klucz sygnatury dostępu współdzielonego w jednostce, którą chcesz opublikować, aby przypisać mu zakres wysyłania. Aby uzyskać więcej informacji, zobacz Zasady autoryzacji dostępu współdzielonego.

  2. Wygeneruj token SAS z upływem czasu wygaśnięcia dla określonego wydawcy przy użyciu klucza wygenerowanego w kroku 1. Aby zapoznać się z przykładowym kodem, zobacz Generowanie sygnatury (tokenu) na podstawie zasad.

  3. Podaj token klientowi wydawcy, który może wysyłać tylko do jednostki i wydawcy, do której token udziela dostępu.

    Po wygaśnięciu tokenu klient utraci dostęp do wysyłania/publikowania w jednostce.

Uwaga

Chociaż nie jest to zalecane, można wyposażyć urządzenia w tokeny, które udzielają dostępu do centrum zdarzeń lub przestrzeni nazw. Każde urządzenie, które zawiera ten token, może wysyłać komunikaty bezpośrednio do tego centrum zdarzeń. Ponadto nie można zablokować wysyłania urządzenia do tego centrum zdarzeń.

Zawsze zaleca się nadanie określonych i szczegółowych zakresów.

Ważne

Po utworzeniu tokenów każdy klient jest aprowizowany przy użyciu własnego unikatowego tokenu.

Gdy klient wysyła dane do centrum zdarzeń, taguje żądanie za pomocą tokenu. Aby zapobiec podsłuchiwania i kradzieży tokenu przez osobę atakującą, komunikacja między klientem a centrum zdarzeń musi odbywać się za pośrednictwem zaszyfrowanego kanału.

W przypadku kradzieży tokenu przez osobę atakującą osoba atakująca może personifikować klienta, którego token został skradziony. Blokowanie na liście wydawcy powoduje, że klient będzie bezużyteczny, dopóki nie otrzyma nowego tokenu używającego innego wydawcy.

Uwierzytelnianie użytkowników usługi Event Hubs przy użyciu sygnatury dostępu współdzielonego

Aby uwierzytelnić aplikacje zaplecza korzystające z danych generowanych przez producentów usługi Event Hubs, uwierzytelnianie tokenu usługi Event Hubs wymaga, aby jego klienci mieli uprawnienia do zarządzania lub uprawnienia nasłuchiwania przypisane do przestrzeni nazw usługi Event Hubs lub wystąpienia lub tematu centrum zdarzeń. Dane są używane z usługi Event Hubs przy użyciu grup odbiorców. Chociaż zasady sygnatury dostępu współdzielonego zapewniają szczegółowy zakres, ten zakres jest definiowany tylko na poziomie jednostki, a nie na poziomie konsumenta. Oznacza to, że uprawnienia zdefiniowane na poziomie przestrzeni nazw lub wystąpienia centrum zdarzeń lub na poziomie tematu zostaną zastosowane do grup odbiorców tej jednostki.

Wyłączanie uwierzytelniania za pomocą klucza lokalnego/sygnatury dostępu współdzielonego

W przypadku niektórych wymagań dotyczących zabezpieczeń organizacji chcesz całkowicie wyłączyć uwierzytelnianie za pomocą klucza lokalnego/sygnatury dostępu współdzielonego i polegać na uwierzytelnianiu opartym na identyfikatorze Entra firmy Microsoft, co jest zalecanym sposobem nawiązywania połączenia z usługą Azure Event Hubs. Uwierzytelnianie za pomocą klucza lokalnego/sygnatury dostępu współdzielonego można wyłączyć na poziomie przestrzeni nazw usługi Event Hubs przy użyciu witryny Azure Portal lub szablonu usługi Azure Resource Manager.

Wyłączanie uwierzytelniania za pomocą klucza lokalnego/sygnatury dostępu współdzielonego za pośrednictwem portalu

Uwierzytelnianie za pomocą klucza lokalnego/sygnatury dostępu współdzielonego dla danej przestrzeni nazw usługi Event Hubs można wyłączyć przy użyciu witryny Azure Portal.

Jak pokazano na poniższej ilustracji, w sekcji Przegląd przestrzeni nazw wybierz pozycję Uwierzytelnianie lokalne.

Omówienie przestrzeni nazw na potrzeby wyłączania lokalnego uwierzytelniania

Następnie wybierz opcję Wyłączone i wybierz przycisk OK , jak pokazano na poniższej ilustracji. Wyłączanie lokalnego uwierzytelniania

Wyłączanie uwierzytelniania za pomocą klucza lokalnego/sygnatury dostępu współdzielonego przy użyciu szablonu

Uwierzytelnianie lokalne dla danej przestrzeni nazw usługi Event Hubs można wyłączyć, ustawiając disableLocalAuth właściwość na true , jak pokazano w poniższym szablonie usługi Azure Resource Manager (szablon usługi 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": false
      },
      "resources": [
        {
          "apiVersion": "2017-04-01",
          "name": "[parameters('eventHubName')]",
          "type": "EventHubs",
          "dependsOn": [
            "[concat('Microsoft.EventHub/namespaces/', parameters('eventHubNamespaceName'))]"
          ],
          "properties": {
            "messageRetentionInDays": "[parameters('messageRetentionInDays')]",
            "partitionCount": "[parameters('partitionCount')]"
          }

        }
      ]
    }
  ]

Przykłady

  • Zobacz przykład platformy .NET #6 w tej lokalizacji usługi GitHub, aby dowiedzieć się, jak publikować zdarzenia w centrum zdarzeń przy użyciu poświadczeń dostępu współdzielonego lub domyślnej tożsamości poświadczeń platformy Azure.
  • Zobacz przykład .NET #5 w tej lokalizacji usługi GitHub, aby dowiedzieć się, jak korzystać z zdarzeń lub przetwarzać je przy użyciu poświadczeń dostępu współdzielonego lub domyślnej tożsamości poświadczeń platformy Azure.

Następne kroki

Odwiedź następujące artykuły:

Zobacz następujące powiązane artykuły: