Controle o acesso ao Serviço de Provisionamento de Dispositivo (DPS) do Hub IoT do Azure com assinaturas de acesso compartilhado e tokens de segurança
Este artigo descreve as opções disponíveis para proteger seu DPS (Serviço de Provisionamento de Dispositivo) do Hub IoT do Azure. O serviço de provisionamento usa autenticação e permissões para conceder acesso a cada ponto de extremidade. As permissões permitem que o processo de autenticação limite o acesso a uma instância de serviço com base na funcionalidade.
Este artigo discute:
O processo de autenticação e os tokens que o serviço de provisionamento usa para verificar as permissões em relação às APIs REST de Serviço e de Dispositivo.
As diferentes permissões que você pode conceder a um aplicativo de back-end para acessar a API de serviço.
Autenticação
A API de dispositivo suporta autenticação de dispositivo baseada em chave e baseada em certificado X.509.
A API de serviço oferece suporte à autenticação baseada em chave para aplicativos de back-end.
Ao usar a autenticação baseada em chave, o Serviço de Provisionamento de Dispositivo usa tokens de segurança para autenticar serviços e evitar o envio de chaves por fio. Além disso, os tokens de segurança são limitados em tempo de validade e escopo. Os SDKs de provisionamento de dispositivo IoT do Azure geram tokens automaticamente sem exigir nenhuma configuração especial.
Em alguns casos, talvez seja necessário usar as APIs REST do Serviço de Provisionamento de Dispositivo HTTP diretamente, sem usar os SDKs. As seções a seguir descrevem como autenticar diretamente nas APIs REST.
Autenticação da API do dispositivo
A API de Dispositivo é usada por dispositivos para atestar o Serviço de Provisionamento de Dispositivos e receber uma conexão do Hub IoT.
Nota
Para receber uma conexão autenticada, os dispositivos devem primeiro ser registrados no Serviço de Provisionamento de Dispositivos por meio de um registro. Use a API de serviço para registrar programaticamente um dispositivo por meio de um registro.
Um dispositivo deve autenticar-se na API do dispositivo como parte do processo de provisionamento. O método que um dispositivo usa para autenticar é definido quando você configura um grupo de inscrição ou um registro individual. Seja qual for o método de autenticação, o dispositivo deve emitir um HTTPS PUT para a seguinte URL para provisionar-se.
https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01
Se estiver usando a autenticação baseada em chave, um token de segurança será passado no cabeçalho da solicitação de Autorização HTTP no seguinte formato:
SharedAccessSignature sig={signature}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
Estrutura de token de segurança para autenticação baseada em chave
O token de segurança é passado no cabeçalho da solicitação de autorização HTTP no seguinte formato:
SharedAccessSignature sig={signature}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
Os valores esperados são:
valor | Description |
---|---|
{signature} |
Uma cadeia de caracteres de assinatura HMAC-SHA256 do formulário: {URL-encoded-resourceURI} + "\n" + expiry . Importante: A chave é decodificada da base64 e usada como chave para fazer o cálculo HMAC-SHA256. |
{expiry} |
UTF8 strings para o número de segundos desde a época 00:00:00 UTC em 1 de janeiro de 1970. |
{URL-encoded-resourceURI} |
Codificação de URL minúscula de {ID_Scope}/registrations/{registration_id} |
{policyName} |
Para a API do dispositivo, esta política é sempre "registo". |
O trecho Python a seguir mostra uma função chamada generate_sas_token
que calcula o token a partir das entradas uri
, key
, policy_name
, expiry
para um registro individual usando um tipo de autenticação de chave simétrica.
from base64 import b64encode, b64decode, encode
from hashlib import sha256
from time import time
from urllib.parse import quote_plus, urlencode
from hmac import HMAC
def generate_sas_token(uri, key, policy_name, expiry=3600):
ttl = time() + expiry
sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))
signature = b64encode(HMAC(b64decode(key), sign_key.encode('utf-8'), sha256).digest())
rawtoken = {
'sr' : uri,
'sig': signature,
'se' : str(int(ttl)),
'skn' : policy_name
}
return 'SharedAccessSignature ' + urlencode(rawtoken)
print(generate_sas_token("myIdScope/registrations/mydeviceregistrationid", "00mysymmetrickey", "registration"))
O resultado deve ser semelhante à seguinte saída:
SharedAccessSignature sr=myIdScope%2Fregistrations%2Fmydeviceregistrationid&sig=SDpdbUNk%2F1DSjEpeb29BLVe6gRDZI7T41Y4BPsHHoUg%3D&se=1630175722&skn=registration
O exemplo a seguir mostra como a assinatura de acesso compartilhado é usada para autenticar com a API do dispositivo.
curl -L -i -X PUT -H 'Content-Type: application/json' -H 'Content-Encoding: utf-8' -H 'Authorization: [token]' -d '{"registrationId": "[registration_id]"}' https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01
Se estiver usando um grupo de registro baseado em chave simétrica, você precisará primeiro gerar uma device symmetric
chave usando a chave do grupo de registro. Use a chave primária ou secundária do grupo de registro para calcular um HMAC-SHA256 da ID de registro do dispositivo. O resultado é então convertido no formato Base64 para obter a chave de dispositivo derivada. Para exibir exemplos de código, consulte Como provisionar dispositivos usando grupos de registro de chave simétrica. Uma vez que a chave simétrica do dispositivo tenha sido derivada, você pode registrar o dispositivo usando os exemplos anteriores.
Aviso
Para evitar incluir a chave mestra de grupo no código do dispositivo, o processo de derivação da chave do dispositivo deve ser feito fora do dispositivo.
Autenticação baseada em certificado
Se você configurou um registro individual ou grupo de inscrição para autenticação baseada em certificado X.509, o dispositivo precisará usar seu certificado X.509 emitido para atestar a API do dispositivo. Consulte os seguintes artigos sobre como configurar o registro e gerar o certificado do dispositivo.
Guia de início rápido - Provisionar dispositivo X.509 simulado para o Hub IoT do Azure
Guia de início rápido - Inscrever dispositivos X.509 no Serviço de Provisionamento de Dispositivos do Azure
Depois que o registro tiver sido configurado e o certificado de dispositivo emitido, o exemplo a seguir demonstra como autenticar na API do dispositivo com o certificado X.509 do dispositivo.
curl -L -i -X PUT –cert ./[device_cert].pem –key ./[device_cert_private_key].pem -H 'Content-Type: application/json' -H 'Content-Encoding: utf-8' -d '{"registrationId": "[registration_id]"}' https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01
Autenticação da API de serviço
A API de serviço é usada para recuperar o estado de registro e remover registros de dispositivo. O serviço também é usado por aplicativos de back-end para gerenciar programaticamente grupos individuais e grupos de inscrição. A API de serviço oferece suporte à autenticação baseada em chave para aplicativos de back-end.
Você deve ter permissões apropriadas para acessar qualquer um dos pontos de extremidade da API de serviço. Por exemplo, um aplicativo de back-end deve incluir um token contendo credenciais de segurança junto com todas as mensagens enviadas ao serviço.
O Serviço de Provisionamento de Dispositivo do Hub IoT do Azure concede acesso a pontos de extremidade verificando o token em relação às políticas de acesso compartilhado. As credenciais de segurança, como chaves simétricas, nunca são enviadas por fio.
Controle de acesso e permissões
Você pode conceder permissões das seguintes maneiras:
Políticas de autorização de acesso compartilhado. As políticas de acesso compartilhado podem conceder qualquer combinação de permissões. Você pode definir políticas no portal do Azure ou programaticamente usando as APIs REST do Serviço de Provisionamento de Dispositivo. Um serviço de provisionamento recém-criado tem a seguinte política padrão:
provisioningserviceowner: Política com todas as permissões. Consulte as permissões para obter informações detalhadas.
Nota
O provedor de recursos do Serviço de Provisionamento de Dispositivo é protegido por meio de sua assinatura do Azure, assim como todos os provedores no Gerenciador de Recursos do Azure.
Para obter mais informações sobre como construir e usar tokens de segurança, consulte a próxima seção.
HTTP é o único protocolo suportado e implementa a autenticação incluindo um token válido no cabeçalho da solicitação de autorização .
Exemplo
SharedAccessSignature sr =
mydps.azure-devices-provisioning.net&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501&skn=provisioningserviceowner`\
Nota
Os SDKs do Serviço de Provisionamento de Dispositivo IoT do Azure geram tokens automaticamente ao se conectar ao serviço.
Tokens de segurança
O Serviço de Provisionamento de Dispositivos usa tokens de segurança para autenticar serviços e evitar o envio de chaves por fio. Além disso, os tokens de segurança são limitados em tempo de validade e escopo. Os SDKs do Serviço de Provisionamento de Dispositivo IoT do Azure geram tokens automaticamente sem exigir nenhuma configuração especial. Alguns cenários exigem que você gere e use tokens de segurança diretamente. Tais cenários incluem o uso direto da superfície HTTP.
Estrutura do token de segurança
Você usa tokens de segurança para conceder acesso limitado no tempo para serviços a funcionalidades específicas no Serviço de Provisionamento de Dispositivos IoT. Para obter autorização para se conectar ao serviço de provisionamento, os serviços devem enviar tokens de segurança assinados com acesso compartilhado ou chave simétrica.
Um token assinado com uma chave de acesso compartilhada concede acesso a todas as funcionalidades associadas às permissões da política de acesso compartilhado.
O token de segurança tem o seguinte formato:
SharedAccessSignature sig={signature}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
Aqui estão os valores esperados
valor | Description |
---|---|
{assinatura} | Uma cadeia de caracteres de assinatura HMAC-SHA256 do formulário: {URL-encoded-resourceURI} + "\n" + expiry . Importante: A chave é decodificada da base64 e usada como chave para fazer o cálculo HMAC-SHA256. |
{prazo de validade} | UTF8 strings para o número de segundos desde a época 00:00:00 UTC em 1 de janeiro de 1970. |
{URL-encoded-resourceURI} | Codificação de URL minúscula do URI de recurso minúsculo. Prefixo de URI (por segmento) dos pontos de extremidade que podem ser acessados com esse token, começando com o nome do host do Serviço de Provisionamento de Dispositivo IoT (sem protocolo). Por exemplo, mydps.azure-devices-provisioning.net . |
{nome_da_política} | O nome da política de acesso compartilhado à qual esse token se refere. |
Nota
O prefixo URI é calculado por segmento e não por caractere. Por exemplo /a/b
, é um prefixo para /a/b/c
, mas não para /a/bc
.
O trecho de Node.js a seguir mostra uma função chamada generateSasToken que calcula o token a partir das entradas resourceUri, signingKey, policyName, expiresInMins
. As próximas seções detalham como inicializar as diferentes entradas para os diferentes casos de uso de token.
var generateSasToken = function(resourceUri, signingKey, policyName, expiresInMins) {
resourceUri = encodeURIComponent(resourceUri);
// Set expiration in seconds
var expires = (Date.now() / 1000) + expiresInMins * 60;
expires = Math.ceil(expires);
var toSign = resourceUri + '\n' + expires;
// Use crypto
var hmac = crypto.createHmac('sha256', new Buffer(signingKey, 'base64'));
hmac.update(toSign);
var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));
// Construct authorization string
var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
+ base64UriEncoded + "&se=" + expires + "&skn="+ policyName;
return token;
};
Como comparação, o código Python equivalente para gerar um token de segurança é:
from base64 import b64encode, b64decode
from hashlib import sha256
from time import time
from urllib.parse import quote_plus, urlencode
from hmac import HMAC
def generate_sas_token(uri, key, policy_name, expiry=3600):
ttl = time() + expiry
sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))
print sign_key
signature = b64encode(HMAC(b64decode(key), sign_key, sha256).digest())
rawtoken = {
'sr' : uri,
'sig': signature,
'se' : str(int(ttl)),
'skn' : policy_name
}
return 'SharedAccessSignature ' + urlencode(rawtoken)
Nota
Como a validade de tempo do token é validada em máquinas do IoT Device Provisioning Service, o desvio no relógio da máquina que gera o token deve ser mínimo.
Usar tokens de segurança de componentes de serviço
Os componentes de serviço só podem gerar tokens de segurança usando políticas de acesso compartilhado que concedem as permissões apropriadas, conforme explicado anteriormente.
Aqui estão as funções de serviço expostas nos pontos de extremidade:
Ponto final | Caraterística |
---|---|
{your-service}.azure-devices-provisioning.net/enrollments |
Fornece operações de registro de dispositivo com o Serviço de Provisionamento de Dispositivos. |
{your-service}.azure-devices-provisioning.net/enrollmentGroups |
Fornece operações para gerenciar grupos de registro de dispositivos. |
{your-service}.azure-devices-provisioning.net/registrations/{id} |
Fornece operações para recuperar e gerenciar o status de registros de dispositivos. |
Por exemplo, um serviço gerado usando uma política de acesso compartilhado pré-criada chamada enrollmentread
criaria um token com os seguintes parâmetros:
- URI do recurso:
{mydps}.azure-devices-provisioning.net
, - chave de assinatura: uma das chaves da
enrollmentread
política, - Nome da política:
enrollmentread
, - qualquer tempo de expiração.backn
var endpoint ="mydps.azure-devices-provisioning.net";
var policyName = 'enrollmentread';
var policyKey = '...';
var token = generateSasToken(endpoint, policyKey, policyName, 60);
O resultado, que daria acesso à leitura de todos os registros de inscrição, seria:
SharedAccessSignature sr=mydps.azure-devices-provisioning.net&sig=JdyscqTpXdEJs49elIUCcohw2DlFDR3zfH5KqGJo4r4%3D&se=1456973447&skn=enrollmentread
SDKs e amostras
Tópicos de referência:
Os tópicos de referência a seguir fornecem mais informações sobre como controlar o acesso ao seu Serviço de Provisionamento de Dispositivos IoT.
Permissões do Serviço de Provisionamento de Dispositivos
A tabela a seguir lista as permissões que você pode usar para controlar o acesso ao seu Serviço de Provisionamento de Dispositivo IoT.
Permissão | Notas |
---|---|
ServiceConfig | Concede acesso para alterar as configurações de serviço. Essa permissão é usada por serviços de nuvem de back-end. |
InscriçãoLer | Concede acesso de leitura às inscrições de dispositivos e grupos de inscrição. Essa permissão é usada por serviços de nuvem de back-end. |
InscriçãoEscrever | Concede acesso de gravação aos registros de dispositivos e grupos de registro. Essa permissão é usada por serviços de nuvem de back-end. |
RegistoEstadoLer | Concede acesso de leitura ao status de registro do dispositivo. Essa permissão é usada por serviços de nuvem de back-end. |
RegistrationStatusWrite | Concede acesso de exclusão ao status de registro do dispositivo. Essa permissão é usada por serviços de nuvem de back-end. |