Ověřování přístupu k prostředkům služby Event Hubs pomocí sdílených přístupových podpisů (SAS)

Sdílený přístupový podpis (SAS) poskytuje podrobnou kontrolu nad typem přístupu, který klientům udělíte. Tady jsou některé ovládací prvky, které můžete nastavit v SAS:

  • Interval platnosti sdíleného přístupového podpisu, který zahrnuje počáteční čas a čas vypršení platnosti.
  • Oprávnění udělená SAS. Například SAS pro obor názvů služby Event Hubs může udělit oprávnění k naslouchání, ale ne oprávnění k odeslání.
  • Do centra událostí můžou odesílat data jenom klienti, kteří prezentují platné přihlašovací údaje.
  • Klient nemůže zosobnit jiného klienta.
  • Neautornímu klientovi je možné zablokovat odesílání dat do centra událostí.

Tento článek popisuje ověřování přístupu k prostředkům služby Event Hubs pomocí SAS. Informace o autorizaci přístupu k prostředkům služby Event Hubs pomocí SAS najdete v tomto článku.

Poznámka:

Microsoft doporučuje používat přihlašovací údaje Microsoft Entra, pokud je to možné jako osvědčený postup zabezpečení, a ne používat sdílené přístupové podpisy, které mohou být snadněji ohroženy. I když můžete dál používat sdílené přístupové podpisy (SAS) k udělení jemně odstupňovaného přístupu k prostředkům služby Event Hubs, Microsoft Entra ID nabízí podobné funkce, aniž by bylo nutné spravovat tokeny SAS nebo se starat o odvolání ohroženého SAS.

Další informace o integraci Microsoft Entra ve službě Azure Event Hubs najdete v tématu Autorizace přístupu ke službě Event Hubs pomocí ID Microsoft Entra.

Konfigurace ověřování SAS

Pravidlo SAS můžete nakonfigurovat pro obor názvů služby Event Hubs nebo entitu (instanci centra událostí nebo téma Kafka v centru událostí). Konfigurace pravidla SAS pro skupinu příjemců se v současné době nepodporuje, ale pro zabezpečení přístupu ke skupině příjemců můžete použít pravidla nakonfigurovaná pro obor názvů nebo entitu.

Následující obrázek ukazuje, jak se pravidla autorizace vztahují na ukázkové entity.

Konfigurace autorizačního pravidla

V tomto příkladu má ukázkový obor názvů Event Hubs (ExampleNamespace) dvě entity: eh1 a téma Kafka1. Autorizační pravidla jsou definována jak na úrovni entity, tak i na úrovni oboru názvů.

Pravidla autorizace manageRuleNS, sendRuleNS a listenRuleNS platí pro autorizační pravidla eh1 i t1. Autorizační pravidla listenRule-eh a sendRule-eh platí pouze pro autorizační pravidlo eh1 a sendRuleT platí jenom pro téma1.

Když použijete autorizační pravidlo sendRuleNS, klientské aplikace můžou odesílat jak do eh1, tak do tématu1. Když se použije autorizační pravidlo sendRuleT, vynucuje podrobný přístup jenom k tématu 1, a proto klientské aplikace používající toto pravidlo pro přístup teď nemůžou posílat na adresu eh1, ale jenom do tématu 1.

Vygenerování tokenu sdíleného přístupového podpisu

Každý klient, který má přístup k názvu autorizačního pravidla a jeden z jeho podpisových klíčů, může vygenerovat token SAS. Token se vygeneruje tak, že vytvoří řetězec v následujícím formátu:

  • se – Platnost tokenu vyprší okamžitě. Celé číslo odrážející sekundy od epochy 00:00:00 UTC dne 1. ledna 1970 (systém UNIX epocha) při vypršení platnosti tokenu
  • skn – Název autorizačního pravidla, což je název klíče SAS.
  • sr – identifikátor URI prostředku, ke kterému se přistupuje.
  • sig –Podpis.

Řetězec podpisu je hodnota hash SHA-256 vypočítaná přes identifikátor URI prostředku (obor, jak je popsáno v předchozí části) a řetězcové vyjádření vypršení platnosti tokenu, které je oddělené crlf. Výpočet hodnoty hash vypadá podobně jako následující pseudokód a vrátí hodnotu hash 256 bitů/32 bajtů.

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

Token obsahuje hodnoty, které nejsou hashovány, aby příjemce mohl hodnotu hash překompilovat stejnými parametry a ověřit, že vystavitel má platný podpisový klíč.

Identifikátor URI prostředku je úplný identifikátor URI prostředku služby Service Bus, ke kterému se má získat přístup. Například http://<namespace>.servicebus.windows.net/<entityPath> , nebo sb://<namespace>.servicebus.windows.net/<entityPath> to znamená http://contoso.servicebus.windows.net/eh1.

Identifikátor URI musí být kódovaný v procentech.

Pravidlo SAS použité k podepisování musí být nakonfigurováno pro entitu určenou tímto identifikátorem URI nebo jedním z jeho hierarchických nadřazených prvků. Například http://contoso.servicebus.windows.net/eh1 nebo http://contoso.servicebus.windows.net v předchozím příkladu.

Token SAS je platný pro všechny prostředky s předponou <resourceURI> použitou v řetězci podpisu.

Poznámka:

Pomocí zásad sdíleného přístupu vygenerujete přístupový token pro službu Event Hubs. Další informace najdete v tématu Zásady autorizace sdíleného přístupu.

Generování podpisu (tokenu) ze zásady

Následující část ukazuje generování tokenu SAS pomocí zásad sdíleného přístupového podpisu.

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

Pokud chcete použít název zásady a hodnotu klíče pro připojení k centru událostí, použijte EventHubProducerClient konstruktor, který přebírá AzureNamedKeyCredential parametr.

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

Musíte přidat odkaz na AzureNamedKeyCredential.

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

Pokud chcete použít token SAS, který jste vygenerovali pomocí kódu, použijte EventHubProducerClient konstruktor, který přebírá AzureSASCredential parametr.

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

Musíte přidat odkaz na 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"
}

Ověřování vydavatelů služby Event Hubs pomocí SAS

Vydavatel události definuje virtuální koncový bod pro centrum událostí. Vydavatel je možné použít pouze k odesílání zpráv do centra událostí a k přijímání zpráv.

Centrum událostí obvykle využívá jednoho vydavatele na klienta. Všechny zprávy, které se odesílají do libovolného vydavatele centra událostí, se začtou do fronty v rámci tohoto centra událostí. Vydavatelé umožňují jemně odstupňované řízení přístupu.

Každému klientovi služby Event Hubs je přiřazen jedinečný token, který se nahraje do klienta. Tokeny se vytvářejí tak, aby každý jedinečný token udělil přístup jinému jedinečnému vydavateli. Klient, který obsahuje token, může odesílat pouze jednomu vydavateli a žádnému jinému vydavateli. Pokud stejný token sdílí více klientů, pak každý z nich sdílí vydavatele.

Všechny tokeny se přiřazují pomocí klíčů SAS. Obvykle jsou všechny tokeny podepsané stejným klíčem. Klienti si klíč neuvědomují, což brání klientům ve výrobě tokenů. Klienti pracují se stejnými tokeny, dokud nevyprší jejich platnost.

Pokud chcete například definovat autorizační pravidla vymezená jenom na odesílání a publikování do služby Event Hubs, musíte definovat autorizační pravidlo pro odesílání. Můžete ho provést na úrovni oboru názvů nebo poskytnout podrobnější rozsah konkrétní entitě (instanci centra událostí nebo téma). Klient nebo aplikace, která je vymezena takovým podrobným přístupem, se nazývá vydavatel služby Event Hubs. Postup je následující:

  1. Vytvořte klíč SAS u entity, kterou chcete publikovat, a přiřaďte mu obor odeslání . Další informace najdete v tématu Zásady autorizace sdíleného přístupu.

  2. Vygenerujte token SAS s časem vypršení platnosti pro konkrétního vydavatele pomocí klíče vygenerovaného v kroku 1. Ukázkový kód najdete v tématu Generování podpisu (tokenu) ze zásady.

  3. Zadejte token klientovi vydavatele, který může odeslat pouze entitě a vydavateli, kterému token udělí přístup.

    Po vypršení platnosti tokenu klient ztratí přístup k odesílání a publikování do entity.

Poznámka:

I když se nedoporučuje, je možné zařízení vybavit tokeny, které udělují přístup k centru událostí nebo oboru názvů. Jakékoli zařízení, které tento token obsahuje, může odesílat zprávy přímo do tohoto centra událostí. Zařízení navíc nemůže být zablokované v odesílání do centra událostí.

Vždy se doporučuje zadat konkrétní a podrobné rozsahy.

Důležité

Po vytvoření tokenů se každý klient zřídí s vlastním jedinečným tokenem.

Když klient odešle data do centra událostí, označí svůj požadavek tokenem. Aby se zabránilo útočníkovi v odposlouchávání a krádeži tokenu, musí komunikace mezi klientem a centrem událostí probíhat přes šifrovaný kanál.

Pokud je token odcizen útočníkem, může útočník zosobnit klienta, jehož token byl odcizen. Zablokování vydavatele, vykreslí ho nepoužitelný, dokud neobdrží nový token, který používá jiného vydavatele.

Ověřování příjemců služby Event Hubs pomocí SAS

Aby bylo možné ověřovat back-endové aplikace, které využívají data generovaná producenty služby Event Hubs, vyžaduje ověření tokenu Event Hubs, aby jeho klienti měli přiřazená oprávnění ke správě nebo oprávnění naslouchání k oboru názvů služby Event Hubs, instanci centra událostí nebo tématu. Data se využívají ze služby Event Hubs pomocí skupin příjemců. Zásady SAS sice poskytují podrobný rozsah, ale tento obor se definuje jenom na úrovni entity, nikoli na úrovni příjemce. To znamená, že oprávnění definovaná na úrovni oboru názvů nebo instance centra událostí nebo na úrovni tématu se použijí na skupiny příjemců dané entity.

Zakázání ověřování pomocí místního klíče nebo klíče SAS

V případě určitých požadavků na zabezpečení organizace chcete úplně zakázat ověřování pomocí místního klíče nebo klíče SAS a spoléhat se na ověřování založené na ID Microsoftu, což je doporučený způsob připojení ke službě Azure Event Hubs. Ověřování pomocí místního klíče nebo klíče SAS můžete zakázat na úrovni oboru názvů služby Event Hubs pomocí webu Azure Portal nebo šablony Azure Resource Manageru.

Zakázání ověřování pomocí místního klíče nebo klíče SAS prostřednictvím portálu

Ověřování pomocí místního klíče /SAS pro daný obor názvů služby Event Hubs můžete zakázat pomocí webu Azure Portal.

Jak je znázorněno na následujícím obrázku, v části Přehled oboru názvů vyberte Místní ověřování.

Přehled oboru názvů pro zakázání místního ověřování

A pak vyberte Možnost Zakázáno a vyberte Ok , jak je znázorněno na následujícím obrázku. Zakázání místního ověřování

Zakázání ověřování pomocí místního klíče nebo klíče SAS pomocí šablony

Místní ověřování pro daný obor názvů služby Event Hubs můžete zakázat nastavením disableLocalAuth vlastnosti tak, jak true je znázorněno v následující šabloně Azure Resource Manageru (šablona 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')]"
          }

        }
      ]
    }
  ]

Ukázky

  • V ukázce .NET č. 6 v tomto umístění GitHubu se dozvíte, jak publikovat události do centra událostí pomocí přihlašovacích údajů sdíleného přístupu nebo výchozí identity přihlašovacích údajů Azure.
  • V ukázce .NET č. 5 v tomto umístění GitHubu se dozvíte, jak využívat nebo zpracovávat události pomocí přihlašovacích údajů sdíleného přístupu nebo výchozí identity přihlašovacích údajů Azure.

Další kroky

Podívejte se na následující články:

Projděte si následující související články: