Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Подпись для совместного доступа (SAS) дает вам детальный контроль над типом доступа, который вы предоставляете клиентам. Вот некоторые элементы управления, которые можно настроить в SAS.
- Интервал, в течение которого SAS действителен и который включает время начала и время истечения срока действия.
- Разрешения, предоставляемые системой SAS. Например, SAS для пространства имен Центров событий может предоставить разрешение на прослушивание события, но не разрешение на отправку событий.
- Только клиенты, предоставляющие действительные учетные данные, могут передать данные в концентратор событий.
- Клиент не может действовать от имени другого клиента.
- Постороннему клиенту можно запретить отправку данных в концентратор событий.
В этой статье рассматривается проверка подлинности доступа к ресурсам концентраторов событий с помощью SAS. Дополнительные сведения о предоставлении доступа к ресурсам концентраторов событий с помощью SAS см. в этой статье.
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— момент истечения срока действия маркера. Целое число, отражающее количество секунд с начала эпохи UNIX (00:00:00 UTC 1 января 1970 г.) до момента, когда истекает срок действия токена. -
skn— имя правила авторизации, которое является именем ключа SAS. -
sr— URI ресурса, к которому осуществляется доступ. -
sig— подпись.
Строка сигнатуры — это хэш SHA-256, вычисляемый по URI ресурса (область, как описано в предыдущем разделе) и строковое представление мгновенного истечения срока действия маркера, разделенное каналом строк (LF). Вычисление хэша напоминает следующий псевдокод и возвращает 256-битное (32-байтное) значение хэша.
SHA-256('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
Вы создаете токен доступа для концентраторов событий, используя политику общего доступа. Дополнительные сведения см. в разделе Политика авторизации общего доступа.
Создание подписи токена на основе политики
В следующем разделе показано создание токена 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 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).
"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')]"
}
}
]
}
]
Samples
- См. пример .NET #6 в этом расположении на GitHub, чтобы узнать, как публиковать события в концентраторе событий с использованием учетных данных для общего доступа или идентификации учетных данных Azure по умолчанию.
- См. пример .NET #5 в этом расположении GitHub, чтобы узнать, как использовать или обрабатывать события с использованием учетных данных общего доступа или удостоверения учетных данных Azure по умолчанию.
Дальнейшие действия
Теперь, когда вы понимаете проверку подлинности SAS, изучите следующие связанные разделы:
Укрепите безопасность центров событий:
- Авторизация доступа с помощью подписей общего доступа — изучите концепции авторизации
- Использование управления доступом на основе ролей Azure (RBAC) — реализация корпоративной безопасности