Toegang tot Event Hubs-resources verifiëren met shared access signatures (SAS)

Shared Access Signature (SAS) biedt u gedetailleerde controle over het type toegang dat u aan de clients verleent. Hier volgen enkele van de besturingselementen die u in een SAS kunt instellen:

  • Het interval waarvoor de SAS geldig is, inclusief de begin- en verlooptijd.
  • De machtigingen die zijn verleend door de SAS. Een SAS voor een Event Hubs-naamruimte kan bijvoorbeeld de luistermachtiging verlenen, maar niet de machtiging voor verzenden.
  • Alleen clients met geldige referenties kunnen gegevens verzenden naar een Event Hub.
  • Een client kan geen andere client imiteren.
  • Een rogue client kan worden geblokkeerd voor het verzenden van gegevens naar een Event Hub.

In dit artikel wordt beschreven hoe u de toegang tot Event Hubs-resources kunt verifiëren met behulp van SAS. Zie dit artikel voor meer informatie over het autoriseren van toegang tot Event Hubs-resources met behulp van SAS.

Notitie

Microsoft raadt u aan om microsoft Entra-referenties te gebruiken als best practice voor beveiliging, in plaats van de handtekeningen voor gedeelde toegang te gebruiken, die gemakkelijker kunnen worden aangetast. Hoewel u shared access signatures (SAS) kunt blijven gebruiken om nauwkeurige toegang te verlenen tot uw Event Hubs-resources, biedt Microsoft Entra ID vergelijkbare mogelijkheden zonder dat u SAS-tokens hoeft te beheren of u zorgen hoeft te maken over het intrekken van een gecompromitteerde SAS.

Zie Toegang tot Event Hubs autoriseren met behulp van Microsoft Entra-id voor meer informatie over Microsoft Entra-integratie in Azure Event Hubs.

Configureren voor SAS-verificatie

U kunt een SAS-regel configureren voor een Event Hubs-naamruimte of een entiteit (Event Hub-exemplaar of Kafka-onderwerp in een Event Hub). Het configureren van een SAS-regel voor een consumentengroep wordt momenteel niet ondersteund, maar u kunt regels gebruiken die zijn geconfigureerd voor een naamruimte of entiteit om de toegang tot consumentengroep te beveiligen.

In de volgende afbeelding ziet u hoe de autorisatieregels van toepassing zijn op voorbeeldentiteiten.

Autorisatieregel configureren

In dit voorbeeld heeft de Event Hubs-voorbeeldnaamruimte (ExampleNamespace) twee entiteiten: eh1 en Kafka topic1. De autorisatieregels worden zowel op entiteitsniveau als op naamruimteniveau gedefinieerd.

De autorisatieregels manageRuleNS, sendRuleNS en listenRuleNS zijn van toepassing op zowel eh1 als t1. De autorisatieregels listenRule-eh en sendRule-eh zijn alleen van toepassing op eh1 en sendRuleT-autorisatieregel is alleen van toepassing op onderwerp1.

Wanneer u sendRuleNS-autorisatieregel gebruikt, kunnen clienttoepassingen verzenden naar zowel eh1 als topic1. Wanneer sendRuleT-autorisatieregel wordt gebruikt, wordt gedetailleerde toegang tot onderwerp1 afgedwongen en daarom kunnen clienttoepassingen die deze regel gebruiken, nu niet naar eh1 verzenden, maar alleen naar onderwerp1.

Een Shared Access Signature-token genereren

Elke client die toegang heeft tot de naam van een autorisatieregelnaam en een van de ondertekeningssleutels kan een SAS-token genereren. Het token wordt gegenereerd door een tekenreeks te maken in de volgende indeling:

  • se – Het verlopen van het token onmiddellijk. Geheel getal dat seconden weergeeft sinds epoch 00:00:00 UTC op 1 januari 1970 (UNIX epoch) wanneer het token verloopt
  • skn – Naam van de autorisatieregel, de SAS-sleutelnaam.
  • sr – URI van de resource die wordt geopend.
  • sig –Handtekening.

De handtekeningtekenreeks is de SHA-256-hash die wordt berekend via de resource-URI (bereik zoals beschreven in de vorige sectie) en de tekenreeksweergave van het token verloopt direct, gescheiden door CRLF. De hash-berekening lijkt op de volgende pseudocode en retourneert een hash-waarde van 256-bits/32-bytes.

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

Het token bevat de niet-hashwaarden, zodat de ontvanger de hash opnieuw kan compileren met dezelfde parameters, waarbij wordt gecontroleerd of de verlener een geldige ondertekeningssleutel heeft.

De resource-URI is de volledige URI van de Service Bus-resource waartoe toegang wordt geclaimd. Bijvoorbeeld, http://<namespace>.servicebus.windows.net/<entityPath> of sb://<namespace>.servicebus.windows.net/<entityPath> dat is, http://contoso.servicebus.windows.net/eh1.

De URI moet procent-gecodeerd zijn.

De SAS-regel die wordt gebruikt voor ondertekening, moet worden geconfigureerd voor de entiteit die is opgegeven door deze URI of door een van de hiërarchische bovenliggende elementen. Bijvoorbeeld, http://contoso.servicebus.windows.net/eh1 of http://contoso.servicebus.windows.net in het vorige voorbeeld.

Een SAS-token is geldig voor alle resources die voorafgegaan zijn door de <resourceURI> resources die in de handtekeningtekenreeks worden gebruikt.

Notitie

U genereert een toegangstoken voor Event Hubs met behulp van beleid voor gedeelde toegang. Zie Autorisatiebeleid voor gedeelde toegang voor meer informatie.

Een handtekening (token) genereren op basis van een beleid

In de volgende sectie ziet u hoe u een SAS-token genereert met behulp van handtekeningbeleid voor gedeelde toegang.

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

Als u een beleidsnaam en een sleutelwaarde wilt gebruiken om verbinding te maken met een Event Hub, gebruikt u de EventHubProducerClient constructor die de AzureNamedKeyCredential parameter gebruikt.

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

U moet een verwijzing naar AzureNamedKeyCredential.

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

Als u een SAS-token wilt gebruiken dat u hebt gegenereerd met behulp van de code, gebruikt u de EventHubProducerClient constructor die de AzureSASCredential parameter gebruikt.

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

U moet een verwijzing naar 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"
}

Event Hubs-uitgevers verifiëren met SAS

Een gebeurtenisuitgever definieert een virtueel eindpunt voor een Event Hub. De uitgever kan alleen worden gebruikt om berichten naar een Event Hub te verzenden en geen berichten te ontvangen.

Normaal gesproken maakt een Event Hub gebruik van één uitgever per client. Alle berichten die naar een van de uitgevers van een Event Hub worden verzonden, worden in die Event Hub geplaatst. Uitgevers maken gedetailleerd toegangsbeheer mogelijk.

Aan elke Event Hubs-client wordt een uniek token toegewezen dat naar de client wordt geüpload. De tokens worden zodanig geproduceerd dat elk uniek token toegang verleent tot verschillende unieke uitgevers. Een client met een token kan alleen verzenden naar één uitgever en geen andere uitgever. Als meerdere clients hetzelfde token delen, deelt elk van deze clients de uitgever.

Alle tokens worden toegewezen met SAS-sleutels. Normaal gesproken worden alle tokens ondertekend met dezelfde sleutel. Clients zijn niet op de hoogte van de sleutel, waardoor clients geen tokens kunnen produceren. Clients werken op dezelfde tokens totdat ze verlopen.

Als u bijvoorbeeld autorisatieregels wilt definiëren die beperkt zijn tot alleen verzenden/publiceren naar Event Hubs, moet u een autorisatieregel voor verzenden definiëren. Dit kan worden gedaan op naamruimteniveau of een gedetailleerder bereik geven aan een bepaalde entiteit (event hubs-instantie of een onderwerp). Een client of een toepassing met een dergelijk gedetailleerd toegangsbereik wordt Event Hubs-uitgever genoemd. Dit doet u als volgt:

  1. Maak een SAS-sleutel op de entiteit die u wilt publiceren om het verzendbereik toe te wijzen. Zie Autorisatiebeleid voor gedeelde toegang voor meer informatie.

  2. Genereer een SAS-token met een verlooptijd voor een specifieke uitgever met behulp van de sleutel die in stap1 is gegenereerd. Zie Een handtekening (token) genereren vanuit een beleid voor de voorbeeldcode.

  3. Geef het token op aan de uitgeverclient, die alleen naar de entiteit kan worden verzonden en de uitgever waartoe dat token toegang verleent.

    Zodra het token is verlopen, verliest de client de toegang tot verzenden/publiceren naar de entiteit.

Notitie

Hoewel het niet wordt aanbevolen, is het mogelijk om apparaten uit te rusten met tokens die toegang verlenen tot een Event Hub of een naamruimte. Elk apparaat dat dit token bevat, kan berichten rechtstreeks naar die Event Hub verzenden. Bovendien kan het apparaat niet worden geblokkeerd voor verzending naar die Event Hub.

Het wordt altijd aanbevolen om specifieke en gedetailleerde bereiken te geven.

Belangrijk

Zodra de tokens zijn gemaakt, wordt elke client ingericht met een eigen uniek token.

Wanneer de client gegevens naar een Event Hub verzendt, wordt de aanvraag met het token gelabeld. Om te voorkomen dat een aanvaller het token afluistert en steelt, moet de communicatie tussen de client en de Event Hub plaatsvinden via een versleuteld kanaal.

Als een token wordt gestolen door een aanvaller, kan de aanvaller de client imiteren waarvan het token is gestolen. Als u een uitgever blokkeert, wordt deze client onbruikbaar gemaakt totdat er een nieuw token wordt ontvangen dat een andere uitgever gebruikt.

Event Hubs-consumenten verifiëren met SAS

Voor het verifiëren van back-endtoepassingen die gebruikmaken van de gegevens die worden gegenereerd door Event Hubs-producenten, vereist Event Hubs-tokenverificatie dat de clients beschikken over de beheerrechten of de luisterbevoegdheden die zijn toegewezen aan de Event Hubs-naamruimte of het event hub-exemplaar of onderwerp. Gegevens worden gebruikt vanuit Event Hubs met behulp van consumentengroepen. Hoewel SAS-beleid u een gedetailleerd bereik biedt, wordt dit bereik alleen gedefinieerd op entiteitsniveau en niet op consumentenniveau. Dit betekent dat de bevoegdheden die zijn gedefinieerd op het niveau van de naamruimte of het Event Hub-exemplaar of het onderwerpniveau, worden toegepast op de consumentengroepen van die entiteit.

Verificatie van lokale/SAS-sleutel uitschakelen

Voor bepaalde beveiligingsvereisten van de organisatie wilt u verificatie van lokale/SAS-sleutels volledig uitschakelen en afhankelijk zijn van de verificatie op basis van Microsoft Entra ID. Dit is de aanbevolen manier om verbinding te maken met Azure Event Hubs. U kunt verificatie van lokale/SAS-sleutels uitschakelen op het niveau van de Event Hubs-naamruimte met behulp van Azure Portal of Azure Resource Manager-sjabloon.

Lokale/SAS-sleutelverificatie uitschakelen via de portal

U kunt verificatie van lokale/SAS-sleutels uitschakelen voor een bepaalde Event Hubs-naamruimte met behulp van Azure Portal.

Zoals wordt weergegeven in de volgende afbeelding, selecteert u in de sectie Overzicht van de naamruimte de optie Lokale verificatie.

Overzicht van naamruimte voor het uitschakelen van lokale verificatie

En selecteer vervolgens de optie Uitgeschakeld en selecteer OK , zoals wordt weergegeven in de volgende afbeelding. Lokale verificatie uitschakelen

Verificatie van lokale/SAS-sleutels uitschakelen met behulp van een sjabloon

U kunt lokale verificatie uitschakelen voor een bepaalde Event Hubs-naamruimte door de eigenschap in te true stellen disableLocalAuth op zoals wordt weergegeven in de volgende Azure Resource Manager-sjabloon (ARM-sjabloon).

"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')]"
          }

        }
      ]
    }
  ]

Voorbeelden

  • Zie het .NET-voorbeeld #6 op deze GitHub-locatie voor meer informatie over het publiceren van gebeurtenissen naar een Event Hub met behulp van referenties voor gedeelde toegang of de standaard-Azure-referentie-id.
  • Zie het .NET-voorbeeld #5 op deze GitHub-locatie voor meer informatie over het gebruiken of verwerken van gebeurtenissen met behulp van referenties voor gedeelde toegang of de standaardidentiteit van Azure-referenties.

Volgende stappen

Zie de volgende artikelen:

Zie de volgende gerelateerde artikelen: