Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Используя сигнатуру общего доступа (SAS), вы можете контролировать тип доступа, который предоставляете клиентам. В SAS можно настроить следующие элементы управления:
- Интервал, в течение которого SAS действителен и который включает время начала и время истечения срока действия.
- Разрешения, предоставляемые системой SAS. Например, SAS для пространства имён Event Hubs может давать разрешение на прослушивание событий, но не разрешение на их отправку.
Аутентификация SAS предоставляет следующие преимущества:
- Только клиенты, предоставляющие действительные учетные данные, могут передать данные в концентратор событий.
- Клиент не может действовать от имени другого клиента.
- Вы можете заблокировать незаконный клиент от отправки данных в хаб событий.
В этой статье рассматривается аутентификация доступа к ресурсам Event Hubs с помощью SAS. Чтобы узнать о авторизации доступа к ресурсам Event Hubs с помощью SAS, см. раздел «Авторизовать доступ к ресурсам Event Hubs с использованием подписей общего доступа».
Note
В качестве лучшей практики безопасности используйте учетные данные Microsoft Entra по возможности вместо общих подписей доступа, которые проще скомпрометировать. Хотя вы можете продолжать использовать подписи общего доступа (SAS) для предоставления детального доступа к ресурсам Центров событий, Microsoft Entra ID предлагает аналогичные возможности без необходимости управлять токенами SAS или беспокоиться о аннулировании аутентификационного токена SAS, который был скомпрометирован.
Дополнительные сведения об интеграции Microsoft Entra в Центры событий Azure см. в разделе "Авторизация доступа к центрам событий" с помощью идентификатора Microsoft Entra.
Настройте аутентификацию SAS
Правило SAS можно настроить в пространстве имен Event Hubs или сущности (Event Hub или Kafka topic). Настройка правила SAS для потребительской группы не поддерживается, но вы можете использовать правила, настроенные на пространстве имён или сущности, чтобы обеспечить доступ к группе потребителей. На следующем рисунке показано, как правила авторизации применяются к примерам сущностей.
В этом примере в примере пространства имен Центров событий (ExampleNamespace) есть две сущности: eh1 и Kafka topic1. Правила авторизации определяются как на уровне сущности, так и на уровне пространства имен.
Правила авторизации manageRuleNS, sendRuleNS и listenRuleNS применяются как к eh1, так и к теме1. Правила авторизации listenRule-eh и sendRule-eh применяются только к eh1, а правило авторизации sendRuleT применяется только к topic1.
При использовании правила авторизации sendRuleNS клиентские приложения могут отправляться как в eh1, так и в topic1. При использовании правила авторизации sendRuleT применяется детальный доступ только к разделу1, поэтому клиентские приложения, использующие это правило для доступа, теперь не могут отправляться в eh1, а только в раздел1.
Генерация токена совместного доступа
Любой клиент, имеющий доступ к имени правила авторизации и одному из его ключей подписания, может создать маркер SAS. Генерируйте токен, создав строку в следующем формате:
-
se— момент истечения срока действия маркера. Целое число отражает секунды с эпохи 00:00:00 UTC 1 января 1970 года (эпоха UNIX), когда токен истекает. -
skn— имя правила авторизации, которое является именем ключа SAS. -
sr— URI ресурса, к которому осуществляется доступ. -
sig— подпись.
Строка подписи — это HMAC-SHA256 хеш, вычислённый над URI ресурса (область действия, как описано в предыдущем разделе), и строковое представление мгновенного истечения токена, разделённое линейным фидом (LF). Введите в хэш один из ключей подписи правила авторизации. Хеш-вычисление возвращает 256-битное/32-байтовое хеш-значение.
HMAC-SHA256(signingKey, 'https://<yournamespace>.servicebus.windows.net/' + '\n' + 1438205742)
Токен содержит нехэшированные значения, чтобы получатель мог повторно вычислить хэш с теми же параметрами и проверить, что у издателя есть действительный ключ подписи.
URI ресурса — это полный URI ресурса служебной шины, к которому запрашивается доступ. Например, 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>, используемым в строке подписи.
Note
Вы генерируете токен доступа для Event Hubs с помощью политики совместного доступа. Дополнительные сведения см. в разделе Политика авторизации общего доступа.
Генерируйте подпись (токен) из политики
В следующем разделе показано, как создать токен SAS с помощью политики подписи общего доступа.
Node.js
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"
}
Аутентифицируйте издателей Event Hubs с помощью SAS
Издатель событий определяет виртуальную конечную точку для концентратора событий. Публикатор можно использовать только для отправки сообщений в узел событий, но не для получения сообщений.
Как правило, концентратор событий использует одного издателя на клиента. Все сообщения, отправленные любому издателю концентратора событий, ставятся в очередь в этом концентраторе событий. Издатели обеспечивают точно детализированный контроль доступа.
Уникальный токен назначается каждому клиенту Event Hubs, который загружается на клиента. Токены создаются таким образом, что каждый уникальный токен предоставляет доступ к разному уникальному издателю. Клиент, имеющий токен, может отправлять данные только одному издателю и ни одному другому издателю. Если несколько клиентов совместно используют один токен, они совместно используют издателя.
Всем токенам назначаются ключи SAS. Как правило, все токены подписываются тем же ключом. Клиенты не знают о ключе, что предотвращает их создание токенов. Клиенты используют одни и те же токены до истечения срока их действия.
Например, чтобы определить правила авторизации, ограниченные только отправкой или публикацией в Event Hubs, нужно определить правило авторизации отправки. Вы можете создать правило на уровне пространства имён или задать более точную область действия для конкретной сущности, например для экземпляра Event Hubs или раздела. Клиент или приложение с таким детализированным доступом называется издателем Event Hubs. Чтобы настроить такую аутентификацию, выполните следующие шаги:
Создайте SAS-ключ на том объекте, в который хотите публиковать, и назначьте ему область отправки . Дополнительные сведения см. в разделе Политики авторизации общего доступа.
Сгенерируйте токен SAS с истечением срока действия для конкретного издателя, используя ключ, который вы создали на шаге 1. Для примера кода см. Генерировать подпись (токен) из политики.
Предоставьте токен клиенту издателя, который может отправлять сообщения только той сущности и тому издателю, доступ к которым предоставляет этот токен.
Когда срок действия токена истекает, клиент теряет доступ к отправке или публикации в этой сущности.
Note
Хотя мы этого не рекомендуем, вы можете оснастить устройства токенами, предоставляющими доступ к хабу событий или пространству имён. Любое устройство с этим маркером может отправлять сообщения непосредственно в концентратор событий. Нельзя заблокировать список устройств для отправки в этот хаб событий.
Рекомендуется предоставить конкретные и детализированные параметры.
Important
Когда вы создаёте токены, каждый клиент получает свой уникальный токен.
Когда клиент отправляет данные в хаб событий, он помечает свой запрос токеном. Чтобы предотвратить перехват и кражу токена злоумышленником, связь между клиентом и концентратором событий необходимо осуществлять по зашифрованному каналу.
Если злоумышленник крадёт токен, он может выдать себя за клиента, у которого был украден токен. Если вы запретите издателя, этот клиент становится непригодным до получения нового токена, использующего другого издателя.
Аутентифицируйте пользователей Event Hubs с помощью SAS
Для аутентификации серверных приложений, использующих данные, созданные производителями Центров событий, аутентификация с помощью маркеров Центров событий требует, чтобы их клиентам были назначены права управления или привилегии прослушивания в пространстве имен Центров событий или экземпляре концентратора событий или разделе. Данные из концентраторов событий потребляются через группы потребителей. Хотя политика SAS обеспечивает детальный уровень доступа, он определяется только на уровне сущности, а не на уровне потребителя. Это означает, что привилегии, определенные на уровне пространства имен или на уровне концентратора событий или топика, применяются к группам потребителей данной сущности.
Отключите локальную или SAS-аутентификацию ключа
Для определенных требований к безопасности организации необходимо полностью отключить проверку подлинности локального или SAS-ключа и использовать проверку подлинности на основе идентификатора Microsoft Entra, которая является рекомендуемым способом подключения к Центры событий Azure. Вы можете отключить проверку подлинности локального ключа/ключа SAS на уровне пространства имен Центров событий с помощью портала Azure или шаблона Azure Resource Manager.
Отключите локальную или SAS-аутентификацию ключей с помощью портала
На портале Azure можно отключить проверку подлинности локального ключа/ключа SAS для данного пространства имен Центров событий.
Перейдите к пространству имен Event Hubs в портале Azure.
На странице обзора выберите "Включена локальная проверка подлинности", как показано на следующем рисунке.
Во всплывающем окне выберите Отключено, и выберите ОК.
Отключите локальную или SAS-аутентификацию ключей с помощью шаблона
Вы можете отключить локальную проверку подлинности для заданного пространства имен Event Hubs, установив disableLocalAuth свойство true как показано в следующем шаблоне Azure Resource Manager (шаблон ARM).
{
"apiVersion": "2024-01-01",
"name": "[parameters('eventHubNamespaceName')]",
"type": "Microsoft.EventHub/Namespaces",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard",
"tier": "Standard"
},
"properties": {
"isAutoInflateEnabled": true,
"maximumThroughputUnits": 7,
"disableLocalAuth": true
},
"resources": [
{
"apiVersion": "2024-01-01",
"name": "[parameters('eventHubName')]",
"type": "EventHubs",
"dependsOn": [
"[concat('Microsoft.EventHub/namespaces/', parameters('eventHubNamespaceName'))]"
],
"properties": {
"messageRetentionInDays": "[parameters('messageRetentionInDays')]",
"partitionCount": "[parameters('partitionCount')]"
}
}
]
}
Samples
- См. пример .NET #6 в этом расположении на GitHub, чтобы узнать, как публиковать события в концентраторе событий с использованием учетных данных для общего доступа или идентификации учетных данных Azure по умолчанию.
- См. пример .NET #5 в этом расположении GitHub, чтобы узнать, как использовать или обрабатывать события с использованием учетных данных общего доступа или удостоверения учетных данных Azure по умолчанию.
Связанные материалы
Теперь, когда вы понимаете аутентификацию SAS, ознакомьтесь с этими связанными статьями:
- Авторизуйте доступ к ресурсам Event Hubs с помощью сигнатур общего доступа — изучите концепции авторизации.
- Авторизуйте доступ к Event Hubs с помощью Microsoft Entra ID — Реализуйте корпоративную безопасность.