공유 액세스 서명을 사용하여 IoT Hub에 대한 액세스 제어

IoT Hub는 SAS(공유 액세스 서명) 토큰을 사용하여 유선으로 키를 보내지 않도록 디바이스 및 서비스를 인증합니다. SAS 토큰을 사용하여 디바이스 및 서비스에서 IoT Hub의 특정 기능에 대한 시간 제한 액세스 권한을 부여합니다. 권한 부여를 얻어 IoT Hub에 연결하려면 디바이스 및 서비스는 공유 액세스 또는 대칭 키 중 하나로 서명된 SAS 토큰을 전송해야 합니다. 대칭 키는 ID 레지스트리에 디바이스 ID로 저장됩니다.

이 문서에서는 다음을 소개합니다.

  • IoT hub에 액세스하기 위해 클라이언트에 부여할 수 있는 다양한 권한
  • IoT Hub 토큰은 사용 권한을 확인하는 데 사용됩니다.
  • 자격 증명을 통해 특정 리소스에 대한 액세스를 제한하는 방법.
  • 기존 디바이스 ID 레지스트리 또는 인증 체계를 사용하는 사용자 지정 디바이스 인증 메커니즘.

참고 항목

클라우드-디바이스 메시지, 디바이스 트윈스, 디바이스 관리 등 이 문서에 언급된 일부 기능은 IoT Hub의 표준 계층에서만 사용할 수 있습니다. 기본 및 표준/무료 IoT Hub 계층에 대한 자세한 내용은 솔루션에 적합한 IoT Hub 계층 선택을 참조하세요.

IoT Hub는 권한을 사용하여 각 IoT Hub의 엔드포인트에 대한 액세스를 부여합니다. 사용 권한은 기능에 따라 IoT Hub에 대한 액세스를 제한합니다. IoT Hub 엔드포인트에 액세스하려면 적절한 권한이 있어야 합니다. 예를 들어 IoT Hub에 보내는 모든 메시지에는 보안 자격 증명을 포함하는 토큰을 포함해야 합니다. 그러나 디바이스 대칭 키와 같은 서명 키는 네트워크를 통해 전송되지 않습니다.

인증 및 권한 부여

인증은 사용자 자신이 누구인지 증명하는 프로세스입니다. 인증은 IoT Hub에 대한 사용자 또는 디바이스의 ID를 확인합니다. 이 프로세스는 AuthN으로 축약되는 경우가 많습니다. 권한 부여는 IoT Hub에서 인증된 사용자 또는 디바이스에 대한 권한을 확인하는 프로세스입니다. 액세스할 수 있는 리소스 및 명령과 해당 리소스 및 명령으로 수행할 수 있는 작업을 지정합니다. 권한 부여는 AuthZ로 축약되는 경우가 많습니다.

이 문서에서는 액세스 키 및 서명된 보안 토큰을 사용하여 권한을 그룹화하고 애플리케이션에 부여할 수 있는 공유 액세스 서명을 사용하는 인증 및 권한 부여에 대해 설명합니다. 대칭 키 또는 공유 액세스 키를 사용하여 IoT Hub를 통해 디바이스를 인증할 수도 있습니다. SAS 토큰은 대칭 키를 각 호출에 연결하여 디바이스에서 IoT Hub에 대해 수행한 각 호출에 대한 인증을 제공합니다.

액세스 제어 및 권한

IoT hub 수준 액세스에 대한 공유 액세스 정책을 사용하고 개별 디바이스 자격 증명을 사용하여 해당 디바이스로만 액세스 범위를 지정합니다.

IoT hub 수준 공유 액세스 정책.

공유 액세스 정책은 모든 조합의 권한을 부여할 수 있습니다. Azure Portal에서 IoT Hub 리소스 REST API를 사용하여 프로그래밍 방식으로 또는 Azure CLI az iot hub policy를 사용하여 정책을 정의할 수 있습니다. 새로 만든 IoT Hub에는 다음과 같은 기본 정책이 있습니다.

공유 액세스 정책 사용 권한
iothubowner 모든 권한
서비스 ServiceConnect 권한
디바이스 DeviceConnect 권한
registryRead RegistryRead 권한
registryReadWrite RegistryReadRegistryWrite 권한

다음 권한을 사용하여 IoT Hub에 대한 액세스를 제어할 수 있습니다.

  • ServiceConnect 권한은 백 엔드 클라우드 서비스에서 사용되며 다음 액세스 권한을 부여합니다.

    • 클라우드 서비스 지향 통신 및 모니터링 중인 엔드포인트에 대한 액세스를 부여합니다.
    • 디바이스-클라우드 메시지를 받고 클라우드-디바이스 메시지를 보내며 해당 전달 승인을 검색합니다.
    • 파일 업로드에 대한 전달 승인을 검색합니다.
    • 태그 및 원하는 속성을 업데이트하고, 보고된 속성을 검색하고, 쿼리를 실행하기 위해 쌍에 액세스합니다.
  • DeviceConnect 권한은 디바이스에서 사용되며 다음 액세스 권한을 부여합니다.

    • 디바이스 지향 엔드포인트에 대한 액세스.
    • 디바이스-클라우드 메시지 전송 및 클라우드-디바이스 메시지 수신.
    • 파일 업로드 수행.
    • 디바이스 쌍의 원하는 속성 알림 수신 및 디바이스 쌍의 보고된 속성 업데이트.
  • RegistryRead 권한은 백 엔드 클라우드 서비스에서 사용되며 다음 액세스 권한을 부여합니다.

    • ID 레지스트리에 대한 읽기 액세스 권한. 자세한 내용은 ID 레지스트리를 참조하세요.
  • RegistryReadWrite 권한은 백 엔드 클라우드 서비스에서 사용되며 다음 액세스 권한을 부여합니다.

    • ID 레지스트리에 대한 읽기 및 쓰기 액세스 권한. 자세한 내용은 ID 레지스트리를 참조하세요.

디바이스 단위 보안 자격 증명.

모든 IoT Hub에는 IoT Hub에 연결이 허용된 디바이스 및 모듈에 대한 정보를 저장하는 ID 레지스트리가 있습니다. 디바이스 또는 모듈을 IoT Hub에 연결할 수 있으려면 IoT Hub의 ID 레지스트리에 해당 디바이스 또는 모듈에 대한 항목이 있어야 합니다. 디바이스 또는 모듈은 ID 레지스트리에 저장된 자격 증명에 따라 IoT Hub로 인증합니다.

SAS 토큰 인증을 사용하도록 디바이스를 등록하는 경우 해당 디바이스는 두 개의 대칭 키를 가져옵니다. 대칭 키는 연결된 디바이스 ID에 대한 DeviceConnect 권한을 부여합니다.

서비스에서 SAS 토큰 사용

서비스는 이전 액세스 제어 및 권한 섹션에서 설명한 대로 적절한 권한을 정의하는 공유 액세스 정책을 사용하여 SAS 토큰을 생성할 수 있습니다.

예를 들어 registryRead라는 미리 생성된 공유 액세스 정책을 사용하는 서비스는 다음 매개 변수로 토큰을 만듭니다.

  • 리소스 URI: {IoT hub name}.azure-devices.net,
  • 서명 키: registryRead 정책의 키 중 하나,
  • 정책 이름: registryRead,
  • 임의의 만료 시간.

예를 들어 다음 코드는 Node.js에 SAS 토큰을 만듭니다.

var endpoint = "myhub.azure-devices.net";
var policyName = 'registryRead';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

ID 레지스트리의 모든 디바이스 ID를 읽을 수 있는 액세스 권한을 부여하는 결과는 다음과 같습니다.

SharedAccessSignature sr=myhub.azure-devices.net&sig=JdyscqTpXdEJs49elIUCcohw2DlFDR3zfH5KqGJo4r4%3D&se=1456973447&skn=registryRead

자세한 예제는 SAS 토큰 생성을 참조하세요.

서비스의 경우 SAS 토큰은 IoT Hub 수준에서만 권한을 부여합니다. 즉, 서비스 정책에 따라 토큰을 사용하여 인증하는 서비스는 ServiceConnect 권한으로 부여된 모든 작업을 수행할 수 있습니다. 이러한 작업에는 디바이스-클라우드 메시지 수신, 클라우드-디바이스 메시지 보내기 등이 포함됩니다. 서비스에 대한 보다 세분화된 액세스 권한을 부여하려는 경우(예: 서비스를 클라우드-디바이스 메시지 보내기로만 제한) Microsoft Entra ID를 사용할 수 있습니다. 자세한 내용은 Microsoft Entra ID로 인증을 참조하세요.

디바이스에서 SAS 토큰 사용

SAS 토큰을 사용하여 IoT Hub에 DeviceConnect 권한을 확보하는 방법은 두 가지입니다. ID 레지스트리의 대칭 디바이스 키를 사용하거나 공유 액세스 키를 사용합니다.

디바이스에서 액세스할 수 있는 모든 기능은 /devices/{deviceId} 접두사가 있는 엔드포인트에서 의도적으로 노출됩니다.

디바이스 연결 엔드포인트는 다음과 같습니다(프로토콜과 관련 없음).

엔드포인트 기능
{iot hub name}/devices/{deviceId}/messages/events 디바이스-클라우드 메시지를 보냅니다.
{iot hub name}/devices/{deviceId}/messages/devicebound 클라우드-디바이스 메시지를 받습니다.

ID 레지스트리에서 대칭 키 사용

디바이스 ID의 대칭 키를 사용하여 토큰을 생성하는 경우 토큰의 policyName(skn) 요소가 생략됩니다.

예를 들어, 모든 디바이스 기능에 액세스하기 위해 만든 토큰은 다음 매개 변수를 포함해야 합니다.

  • 리소스 URI: {IoT hub name}.azure-devices.net/devices/{device id},
  • 서명 키: {device id} ID에 대한 모든 대칭 키,
  • 정책 이름 없음,
  • 임의의 만료 시간.

예를 들어 다음 코드는 Node.js에 SAS 토큰을 만듭니다.

var endpoint ="myhub.azure-devices.net/devices/device1";
var deviceKey ="...";

var token = generateSasToken(endpoint, deviceKey, null, 60);

device1의 모든 기능에 액세스 권한을 부여하는 결과는 다음과 같습니다.

SharedAccessSignature sr=myhub.azure-devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697

자세한 예제는 SAS 토큰 생성을 참조하세요.

공유 액세스 정책을 사용하여 디바이스를 대신해서 액세스

공유 액세스 정책에서 토큰을 만들 때 skn 필드를 정책의 이름으로 설정합니다. 이 정책은 DeviceConnect 권한을 부여해야 합니다.

디바이스 기능에 액세스하는 데 공유 액세스 정책을 사용하는 두 가지 주요 시나리오는 다음과 같습니다.

공유 액세스 정책은 모든 디바이스로 연결하기 위해 잠재적으로 액세스 권한을 부여할 수 있으므로 SAS 토큰을 만들 때 올바른 리소스 URI를 사용하는 것이 중요합니다. 이 설정은 리소스 URI를 사용하여 토큰을 특정 디바이스로 범위를 제한해야 하는 토큰 서비스에서 특히 중요합니다. 프로토콜 게이트웨이는 모든 디바이스에 대한 트래픽을 이미 조정하므로 관련성이 떨어집니다.

예를 들어 디바이스라는 미리 생성된 공유 액세스 정책을 사용하는 토큰 서비스는 다음 매개 변수로 토큰을 만듭니다.

  • 리소스 URI: {IoT hub name}.azure-devices.net/devices/{device id},
  • 서명 키: device 정책의 키 중 하나,
  • 정책 이름: device,
  • 임의의 만료 시간.

예를 들어 다음 코드는 Node.js에 SAS 토큰을 만듭니다.

var endpoint ="myhub.azure-devices.net/devices/device1";
var policyName = 'device';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

device1의 모든 기능에 액세스 권한을 부여하는 결과는 다음과 같습니다.

SharedAccessSignature sr=myhub.azure-devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697&skn=device

프로토콜 게이트웨이는 리소스 URI를 myhub.azure-devices.net/devices로 설정하여 모든 디바이스에 대해 동일한 토큰을 사용할 수 있습니다.

자세한 예제는 SAS 토큰 생성을 참조하세요.

기존 디바이스를 통합하는 토큰 서비스 만들기

IoT Hub ID 레지스트리를 사용하여 토큰을 통해 디바이스별 또는 모듈별 보안 자격 증명 및 액세스 제어를 구성할 수 있습니다. IoT 솔루션에 이미 사용자 지정 ID 레지스트리 및/또는 인증 체계가 있는 경우 토큰 서비스를 만들어 이 인프라를 IoT Hub와 통합할 수 있습니다. 이러한 방식으로 솔루션에서 다른 IoT 기능을 사용할 수 있습니다.

토큰 서비스는 사용자 지정 클라우드 서비스입니다. DeviceConnect 권한으로 IoT Hub 공유 액세스 정책을 사용하여 device-scoped 또는 module-scoped 토큰을 만듭니다. 이러한 토큰은 디바이스 또는 모듈에서 IoT Hub에 연결할 수 있게 해줍니다.

토큰 서비스 패턴의 단계를 보여 주는 다이어그램

토큰 서비스 패턴의 주요 단계는 다음과 같습니다.

  1. IoT Hub에 대한 DeviceConnect 권한으로 IoT Hub 공유 액세스 정책을 만듭니다. Azure Portal 또는 프로그래밍 방식으로 이 정책을 만들 수 있습니다. 토큰 서비스는 이 정책을 사용하여 만들어지는 토큰을 서명합니다.

  2. 디바이스 또는 모듈에서 IoT Hub에 액세스해야 하는 경우 토큰 서비스에 서명된 토큰을 요청합니다. 디바이스는 사용자 지정 ID 레지스트리/인증 체계로 인증하여 토큰 서비스가 토큰을 만드는 데 사용하는 디바이스/모듈 ID를 확인할 수 있습니다.

  3. 토큰 서비스는 토큰을 반환합니다. 토큰은 인증되는 디바이스의 deviceId 또는 인증되는 모듈의 moduleId와 함께 /devices/{deviceId} 또는 /devices/{deviceId}/modules/{moduleId}resourceURI로 사용하여 생성됩니다. 토큰 서비스는 공유 액세스 정책을 사용하여 토큰을 생성합니다.

  4. 디바이스/모듈은 IoT Hub에서 직접 토큰을 사용합니다.

참고 항목

.NET 클래스 SharedAccessSignatureBuilder 또는 Java 클래스 IotHubServiceSasToken을 사용하여 토큰 서비스에서 토큰을 만들 수 있습니다.

토큰 서비스는 토큰 만료를 원하는 대로 설정할 수 있습니다. 토큰이 만료되면 IoT Hub가 디바이스/모듈 연결을 끊습니다. 이렇게 되면 디바이스/모듈이 토큰 서비스에 새 토큰을 요청해야 합니다. 만료 시간이 짧으면 디바이스/모듈 및 토큰 서비스에 대한 부하가 증가합니다.

허브에 연결하는 디바이스/모듈의 경우, 연결에 키가 아니라 토큰을 사용하더라도 IoT Hub ID 레지스트리에 디바이스/모듈을 추가해야 합니다. 따라서 ID 레지스트리에서 디바이스/모듈 ID를 활성화 또는 비활성화하여 디바이스별/모듈별 액세스 제어를 계속 사용할 수 있습니다. 이 방법은 긴 만료 시간으로 토큰을 사용하는 위험을 완화합니다.

사용자 지정 게이트웨이와 비교

IoT Hub에 사용자 지정 ID 레지스트리/인증 구성표를 구현하는 데는 토큰 서비스 패턴을 사용하는 것이 좋습니다. 이 패턴은 IoT Hub에서 대부분의 솔루션 트래픽을 처리할 수 있어 권장됩니다. 그러나 사용자 지정 인증 체계가 프로토콜과 얽혀있는 경우, 모든 트래픽을 처리하기 위해 사용자 지정 게이트웨이가 필요할 수 있습니다. TLS(전송 계층 보안) 및 PSK(미리 공유한 키) 사용을 이러한 시나리오의 예로 들 수 있습니다. 자세한 내용은 IoT Edge 디바이스를 게이트웨이로 사용하는 방법을 참조하세요.

SAS 토큰 생성

Azure IoT SDK는 토큰을 자동으로 생성하지만, 일부 시나리오에서는 다음을 포함하여 SAS 토큰을 직접 생성하고 사용해야 합니다.

  • MQTT, AMQP 또는 HTTPS 표면을 직접 사용합니다.

  • 토큰 서비스 만들기 섹션에 설명된 대로 토큰 서비스 패턴의 구현.

공유 액세스 키로 서명된 토큰은 공유 액세스 정책 권한과 관련된 모든 기능에 대한 액세스를 부여합니다. 디바이스 ID의 대칭 키로만 서명된 토큰은 관련된 디바이스 ID에 대한 DeviceConnect 권한만을 부여합니다.

이 섹션에서는 다양한 코드 언어로 SAS 토큰을 생성하는 예제를 제공합니다. CLI 확장 명령 az iot hub generate-sas-token 또는 Visual Studio Code용 Azure IoT Hub 확장을 사용하여 SAS 토큰을 생성할 수도 있습니다.

SAS 토큰 구조

SAS 토큰의 형식은 다음과 같습니다.

SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}

다음은 예상 값입니다.

설명
{signature} 형식의 HMAC-SHA256 서명 문자열은 {URL-encoded-resourceURI} + "\n" + expiry입니다. 중요: 키는 base64에서 디코딩되며 HMAC-SHA256 계산을 수행하는 데 키로 사용됩니다.
{resourceURI} 이 토큰으로 액세스할 수 있는 엔드포인트의 URI 접두사(세그먼트별)이며 IoT Hub의 호스트 이름으로 시작합니다(프로토콜 없음). 백 엔드 서비스에 부여된 SAS 토큰은 IoT 허브 수준으로 범위가 지정됩니다(예: myHub.azure-devices.net). 디바이스에 부여된 SAS 토큰은 개별 디바이스로 범위가 지정되어야 합니다(예: myHub.azure-devices.net/devices/device1).
{expiry} 1970년 1월 1일 epoch 0시 UTC 이후의 초 수에 대한 UTF8 문자열입니다.
{URL-encoded-resourceURI} 소문자 URL-소문자 리소스 URI의 인코딩
{policyName} 이 토큰을 참조하는 공유 액세스 정책의 이름입니다. 토큰이 디바이스 레지스트리 자격 증명을 참조하는 경우 없습니다.

문자가 아니라 세그먼트에 의해 계산된 URI 접두사입니다. 예를 들어 /a/b/a/b/c에 대한 접두사이지만 /a/bc에 대한 접두사는 아닙니다.

다음 코드는 리소스 URI, 서명 키, 정책 이름 및 만료 기간을 사용하여 SAS 토큰을 생성합니다. 다음 섹션에서는 여러 토큰 사용 사례에 대해 서로 다른 입력을 초기화하는 방법을 자세히 설명합니다.

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', Buffer.from(signingKey, 'base64'));
    hmac.update(toSign);
    var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));

    // Construct authorization string
    var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
    + base64UriEncoded + "&se=" + expires;
    if (policyName) token += "&skn="+policyName;
    return token;
};

프로토콜 세부 사항

지원되는 각 프로토콜(예: MQTT, AMQP 및 HTTPS)은 다양한 방식으로 토큰을 전송합니다.

MQTT를 사용하는 경우 CONNECT 패킷에는 사용자 이름 필드의 ClientId, {iothubhostname}/{deviceId}에 deviceId, 암호 필드에 SAS 토큰이 있습니다. {iothubhostname}은 IoT Hub의 전체 CName이어야 합니다(예: myhub.azure-devices.net).

AMQP을 사용하는 경우 IoT Hub는 SASL PLAINAMQP 클레임 기반-보안을 지원합니다.

AMQP 클레임-기반-보안을 사용하는 경우 표준은 해당 토큰을 전송하는 방법을 지정합니다.

SASL PLAIN의 경우 사용자 이름 은 다음이 될 수 있습니다.

  • {policyName}@sas.root.{iothubName} IoT Hub 수준 토큰을 사용하는 경우입니다.
  • {deviceId}@sas.{iothubname} 디바이스 범위 토큰을 사용하는 경우입니다.

두 가지 경우 모두 암호 필드에는 SAS 토큰 구조에서 설명된 대로 토큰이 포함됩니다.

HTTPS는 권한 부여 요청 헤더에서 유효한 토큰을 포함하여 인증을 구현합니다.

예: 사용자 이름(DeviceId는 대/소문자 구분): iothubname.azure-devices.net/DeviceId

암호(CLI 확장 명령 az iot hub generate-sas-token 또는 Visual Studio Code용 Azure IoT Hub 확장을 사용하여 SAS 토큰을 생성할 수 있음):

SharedAccessSignature sr=iothubname.azure-devices.net%2fdevices%2fDeviceId&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501

참고 항목

Azure IoT SDK는 서비스에 연결할 때 토큰을 자동으로 생성합니다. 일부 경우에 Azure IoT SDK는 모든 프로토콜 또는 모든 인증 방법을 지원하지 않습니다.

SASL PLAIN에 대한 특별 고려 사항

AMQP와 SASL PLAIN을 사용할 때 IoT Hub에 연결한 클라이언트는 각 TCP 연결에 단일 토큰을 사용할 수 있습니다. 토큰이 만료될 때 TCP 연결은 서비스에서 연결을 끊고 다시 연결을 트리거합니다. 이 동작은 백 엔드 앱에 문제를 발생시키지 않는 반면, 다음과 같은 이유로 디바이스 앱에 피해를 줍니다.

  • 게이트웨이가 일반적으로 많은 디바이스를 대신하여 연결됩니다. SASL PLAIN을 사용할 때 IoT Hub에 연결한 각 디바이스에 고유한 TCP 연결을 만들어야 합니다. 이 시나리오는 전원 및 네트워킹 리소스의 소비를 상당히 증가시키고 각 디바이스 연결의 대기 시간을 늘립니다.

  • 각 토큰이 만료 후에 다시 연결하기 위해 리소스의 사용이 증가하여 리소스가 제한된 디바이스에 부정적인 영향을 미칩니다.

다음 단계

IoT Hub 액세스를 제어하는 방법에 대해 알아봤으니 다음과 같은 IoT Hub 개발자 가이드 항목을 살펴보세요.