

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 사용자 지정 인증 및 권한 부여
<a name="custom-authentication"></a>

 AWS IoT Core 를 사용하면 사용자 지정 권한 부여자를 정의하여 자체 클라이언트 인증 및 권한 부여를 관리할 수 있습니다. 이는에서 AWS IoT Core 기본적으로 지원하는 인증 메커니즘 이외의 인증 메커니즘을 사용해야 하는 경우에 유용합니다. (기본적으로 지원되는 메커니즘에 대한 자세한 내용은 [클라이언트 인증](client-authentication.md) 단원을 참조하세요).  

 예를 들어 필드의 기존 디바이스를 로 마이그레이션 AWS IoT Core 하고 이러한 디바이스가 사용자 지정 보유자 토큰 또는 MQTT 사용자 이름과 암호를 사용하여 인증하는 경우 새 자격 증명을 프로비저닝 AWS IoT Core 하지 않고도 로 마이그레이션할 수 있습니다. 가 AWS IoT Core 지원하는 모든 통신 프로토콜에서 사용자 지정 인증을 사용할 수 있습니다. AWS IoT Core 이(가) 지원하는 프로토콜 및 포트에 대한 자세한 내용은 [디바이스 통신 프로토콜](protocols.md) 단원을 참조하세요.

**Topics**
+ [사용자 지정 인증 워크플로 이해](custom-authorizer.md)
+ [사용자 지정 권한 부여자 생성 및 관리(CLI)](config-custom-auth.md)
+ [X.509 클라이언트 인증서를 사용한 사용자 지정 인증](custom-auth-509cert.md)
+ [사용자 지정 인증을 사용하여 AWS IoT Core 에 연결](custom-auth.md)
+ [Lambda 권한 부여자 문제 해결](custom-auth-troubleshooting.md)

# 사용자 지정 인증 워크플로 이해
<a name="custom-authorizer"></a>

사용자 지정 인증은 [권한 부여자 리소스](https://docs.aws.amazon.com/iot/latest/apireference/API_AuthorizerDescription.html)를 사용하여 클라이언트를 인증하고 권한을 부여하는 방법을 정의할 수 있도록 합니다.   각 권한 부여자에는 고객 관리형 Lambda 함수에 대한 참조, 디바이스 자격 증명을 검증하기 위한 공개 키 옵션 및 추가 구성 정보가 포함되어 있습니다. 다음 다이어그램은 AWS IoT Core에서 사용자 지정 인증에 대한 권한 부여 워크플로를 보여 줍니다.

![\[AWS IoT Core에서 사용자 지정 인증을 위한 사용자 지정 권한 부여 워크플로입니다.\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/images/custom-authentication.png)


## AWS IoT Core 사용자 지정 인증 및 권한 부여 워크플로
<a name="custom-authentication-workflow"></a>

다음 목록에서는 사용자 지정 인증 및 권한 부여 워크플로의 각 단계를 설명합니다.

1. 디바이스는 지원되는 중 하나를 사용하여 고객의 AWS IoT Core 데이터 엔드포인트에 연결합니다[디바이스 통신 프로토콜](protocols.md). 디바이스는 요청의 헤더 필드 또는 쿼리 파라미터(HTTP Publish 또는 WebSockets 프로토콜을 통한 MQTT의 경우) 중 하나에서, 또는 MQTT CONNECT 메시지의 사용자 이름 및 암호 필드(MQTT 및 WebSockets 프로토콜을 통한 MQTT의 경우)에서 자격 증명을 전달합니다.

1. AWS IoT Core 는 다음 두 가지 조건 중 하나를 확인합니다.
   + 수신되는 요청이 권한 부여자를 지정합니다.
   + 요청을 수신하는 AWS IoT Core 데이터 엔드포인트에는 기본 권한 부여자가 구성되어 있습니다.

   가 이러한 방법 AWS IoT Core 중 하나로 권한 부여자를 AWS IoT Core 찾으면는 권한 부여자와 연결된 Lambda 함수를 트리거합니다.

1.  (선택 사항) 토큰 서명을 활성화한 경우는 Lambda 함수를 트리거하기 전에 권한 부여자에 저장된 퍼블릭 키를 사용하여 요청 서명을 AWS IoT Core 확인합니다. 유효성 검사에 실패하면 AWS IoT Core 이(가) Lambda 함수를 호출하지 않고 요청을 중지합니다.  

1. Lambda 함수는 요청에서 자격 증명 및 연결 메타데이터를 수신하고 인증 결정을 내립니다.

1. Lambda 함수는 인증 결정 결과와 연결에서 허용되는 작업을 지정하는 AWS IoT Core 정책 문서를 반환합니다. 또한 Lambda 함수는가 Lambda 함수를 호출하여 요청의 자격 증명을 AWS IoT Core 재검증하는 빈도를 지정하는 정보도 반환합니다.

1. AWS IoT Core 는 Lambda 함수에서 수신한 정책을 기준으로 연결에 대한 활동을 평가합니다.

1. 연결이 설정되고 사용자 지정 권한 부여자 Lambda가 처음 호출되면 MQTT 작업 없이 유휴 연결에서 다음 간접 호출을 최대 5분 동안 지연할 수 있습니다. 그런 다음 후속 간접 호출은 사용자 지정 권한 부여자 Lambda의 새로 고침 간격을 따릅니다. 이 접근 방식은의 Lambda 동시성 제한을 초과할 수 있는 과도한 호출을 방지할 수 있습니다 AWS 계정.

## 스케일 아웃 고려 사항
<a name="custom-authentication-scaling"></a>

 Lambda 함수는 권한 부여자에 대한 인증 및 권한 부여를 처리하므로 동시 실행 속도와 같은 Lambda 요금 및 서비스 제한이 적용됩니다. Lambda 요금에 대한 자세한 내용은 [Lambda 요금](https://aws.amazon.com/lambda/pricing/) 단원을 참조하세요. Lambda 함수 응답에서 `refreshAfterInSeconds` 및 `disconnectAfterInSeconds` 파라미터를 조정하여 Lambda 함수의 로드를 관리할 수 있습니다. Lambda 함수 응답의 내용에 대한 자세한 내용은 [Lambda 함수 정의](custom-auth-lambda.md) 단원을 참조하세요.

**참고**  
서명을 활성화한 상태로 두면 인식할 수 없는 클라이언트가 Lambda를 과도하게 트리거하는 것을 방지할 수 있습니다. 권한 부여자의 로그인을 비활성화하기 전에 이 점을 고려하세요.

**참고**  
사용자 지정 권한 부여자에 대한 Lambda 함수 제한 시간은 5초입니다.

# 사용자 지정 권한 부여자 생성 및 관리(CLI)
<a name="config-custom-auth"></a>

AWS IoT Core 는 사용자 지정 권한 부여자를 사용하여 사용자 지정 인증 및 권한 부여 체계를 구현합니다. 사용자 지정 권한 부여자는 특정 요구 사항에 따라 규칙과 정책을 정의하고 구현할 수 있는 유연성을 제공하는 AWS IoT Core 리소스입니다. 단계별 지침에 따라 사용자 지정 권한 부여자를 생성하려면 [Tutorial: Creating a custom authorizer for AWS IoT Core](https://docs.aws.amazon.com//iot/latest/developerguide/custom-auth-tutorial.html)를 참조하세요.

각 권한 부여자는 다음과 같은 구성 요소로 이루어집니다.
+  *이름*: 권한 부여자를 식별하는 고유한 사용자 정의 문자열입니다.
+  *ARN Lambda 함수*: 권한 부여 및 인증 논리를 구현하는 Lambda 함수의 Amazon 리소스 이름(ARN)입니다.  
+  *토큰 키 이름*: 서명 유효성 검사를 수행하기 위해 HTTP 헤더, 쿼리 파라미터 또는 MQTT CONNECT 사용자 이름에서 토큰을 추출하는 데 사용되는 키 이름입니다. 권한 부여자에서 서명이 활성화된 경우 이 값이 필요합니다.
+  *서명 비활성화 플래그(선택 사항)*: 자격 증명에서 서명 요구 사항을 사용하지 않도록 설정할지 여부를 지정하는 부울 값입니다. 이 기능은 MQTT 사용자 이름 및 암호를 사용하는 인증 스키마와 같이 자격 증명에 서명하는 것이 의미가 없는 시나리오에 유용합니다. 기본값은 `false`(으)로 설정되어 있으므로 기본적으로 서명이 활성화됩니다.
+  *토큰 서명 공개 키*: AWS IoT Core 이(가) 토큰 서명의 유효성을 검사하는 데 사용하는 퍼블릭 키입니다. 최소 길이는 2,048비트입니다. 권한 부여자에서 서명이 활성화된 경우 이 값이 필요합니다.  

Lambda는 Lambda 함수가 실행되는 횟수와 함수의 코드가 실행되는 데 걸리는 시간에 대해 요금을 청구합니다. Lambda 요금에 대한 자세한 내용은 [Lambda 요금](https://aws.amazon.com/lambda/pricing/)을 참조하세요. Lambda 함수에 대한 자세한 내용은 [Lambda 개발자 가이드](https://docs.aws.amazon.com/lambda/latest/dg/)를 참조하세요.

**참고**  
서명을 활성화한 상태로 두면 인식할 수 없는 클라이언트가 Lambda를 과도하게 트리거하는 것을 방지할 수 있습니다. 권한 부여자의 로그인을 비활성화하기 전에 이 점을 고려하세요.

**참고**  
사용자 지정 권한 부여자에 대한 Lambda 함수 제한 시간은 5초입니다.

**Topics**
+ [Lambda 함수 정의](custom-auth-lambda.md)
+ [권한 부여자 생성](custom-auth-create-authorizer.md)
+ [Lambda 함수 AWS IoT 호출 권한 부여](custom-auth-authorize.md)
+ [권한 부여자 테스트](custom-auth-testing.md)
+ [사용자 지정 권한 부여자 관리](custom-auth-manage.md)

# Lambda 함수 정의
<a name="custom-auth-lambda"></a>

 가 권한 부여자를 AWS IoT Core 호출하면 다음 JSON 객체가 포함된 이벤트와 함께 권한 부여자와 연결된 Lambda가 트리거됩니다. 예제 JSON 객체에는 가능한 모든 필드가 포함되어 있습니다. 연결 요청과 관련이 없는 필드는 포함되지 않습니다.

```
{
    "token" :"aToken",
    "signatureVerified": Boolean, // Indicates whether the device gateway has validated the signature.
    "protocols": ["tls", "http", "mqtt"], // Indicates which protocols to expect for the request.
    "protocolData": {
        "tls" : {
            "serverName": "serverName" // The server name indication (SNI) host_name string.
        },
        "http": {
            "headers": {
                "#{name}": "#{value}"
            },
            "queryString": "?#{name}=#{value}"
        },
        "mqtt": {
            "username": "myUserName",
            "password": "myPassword", // A base64-encoded string.
            "clientId": "myClientId" // Included in the event only when the device sends the value.
        }
    },
    "connectionMetadata": {
        "id": UUID // The connection ID. You can use this for logging.
    },
}
```

 Lambda 함수는 이 정보를 사용하여 들어오는 연결을 인증하고 연결에 허용되는 작업을 결정해야 합니다. 함수는 다음 값을 포함하는 응답을 전송해야 합니다.
+  `isAuthenticated`: 요청 인증 여부를 나타내는 부울 값입니다.
+  `principalId`: 사용자 지정 권한 부여 요청에서 전송되는 토큰의 식별자 역할을 하는 영숫자 문자열입니다. 값은 1\$1128자의 영숫자 문자열이어야 하며 정규식(regex) 패턴 `([a-zA-Z0-9]){1,128}`과 일치해야 합니다. 영숫자가 아닌 특수 문자는 `principalId`에서와 함께 사용할 수 없습니다 AWS IoT Core. 에 영숫자가 아닌 특수 문자가 허용되는 경우 다른 AWS 서비스에 대한 설명서를 참조하세요`principalId`.
+  `policyDocuments`: JSON 형식의 AWS IoT Core 정책 문서 목록 AWS IoT Core 정책 생성에 대한 자세한 내용은 섹션을 참조하세요[AWS IoT Core 정책](iot-policies.md). 정책 문서의 최대 수는 10개의 정책 문서입니다. 각 정책 문서는 최대 2,048자를 포함할 수 있습니다.
+  `disconnectAfterInSeconds`: AWS IoT Core 게이트웨이에 대한 연결의 최대 지속 시간(초)을 지정하는 정수입니다. 최소값은 300초이고 최대값은 86,400초입니다. 기본값은 86,400입니다.
**참고**  
`disconnectAfterInSeconds`(Lambda 함수에서 반환됨) 값은 연결이 설정될 때 설정됩니다. 후속 정책 새로 고침 Lambda 간접 호출 중에는 이 값을 수정할 수 없습니다.
+  `refreshAfterInSeconds`: 정책 새로 고침 사이의 간격을 지정하는 정수입니다. 이 간격이 경과하면 AWS IoT Core 은(는) Lambda 함수를 호출하여 정책 새로 고침을 허용합니다. 최소값은 300초이고 최대값은 86,400초입니다.

  다음 JSON 객체에는 Lambda 함수가 전송할 수 있는 응답의 예가 들어 있습니다.

 **\$1 "isAuthenticated":true, //A Boolean that determines whether client can connect. "principalId": "xxxxxxxx",  //A string that identifies the connection in logs. "disconnectAfterInSeconds": 86400,  "refreshAfterInSeconds": 300,   "policyDocuments": [       \$1         "Version": "2012-10-17",         "Statement": [            \$1               "Action": "iot:Publish",               "Effect": "Allow",               "Resource": "arn:aws:iot:us-east-1:<your\$1aws\$1account\$1id>:topic/customauthtesting"             \$1          ]        \$1     ] \$1**

 `policyDocument` 값에는 유효한 AWS IoT Core 정책 문서가 포함되어야 합니다. AWS IoT Core 정책에 대한 자세한 내용은 섹션을 참조하세요[AWS IoT Core 정책](iot-policies.md).  MQTT over TLS 및 MQTT over WebSockets 연결에서 `refreshAfterInSeconds` 필드 값에 지정된 간격 동안이 정책을 AWS IoT Core 캐시합니다. HTTP 연결의 경우 디바이스가 HTTP 지속 연결(HTTP 연결 유지 또는 HTTP 연결 재사용이라고도 함)을 사용하지 않는 한 모든 권한 부여 요청에 대해 Lambda 함수가 호출됩니다. 권한 부여자를 구성할 때 캐싱을 사용하도록 선택할 수 있습니다. 이 간격 동안는 Lambda 함수를 다시 트리거하지 않고이 캐시된 정책에 대해 설정된 연결의 작업을 AWS IoT Core 승인합니다. 사용자 지정 인증 중에 오류가 발생하면는 연결을 AWS IoT Core 종료합니다. AWS IoT Core 또한 `disconnectAfterInSeconds`파라미터에 지정된 값보다 오래 열려 있으면 연결을 종료합니다.

 다음 JavaScript에는 값이 인 MQTT Connect 메시지에서 암호를 찾고 이름이 인 클라이언트 AWS IoT Core 와 연결하고 동일한 클라이언트 이름이 포함된 주제에 `myClientName` 게시할 수 있는 권한을 부여하는 정책을 `test` 반환하는 샘플 Node.js Lambda 함수가 포함되어 있습니다. 예상된 암호를 찾지 못하면 이 두 작업을 거부하는 정책을 반환합니다.

```
// A simple Lambda function for an authorizer. It demonstrates 
// how to parse an MQTT password and generate a response.

exports.handler = function(event, context, callback) { 
    var uname = event.protocolData.mqtt.username;
    var pwd = event.protocolData.mqtt.password;
    var buff = new Buffer(pwd, 'base64');
    var passwd = buff.toString('ascii');
    switch (passwd) { 
        case 'test': 
            callback(null, generateAuthResponse(passwd, 'Allow')); 
            break;
        default: 
            callback(null, generateAuthResponse(passwd, 'Deny'));  
    }
};

// Helper function to generate the authorization response.
var generateAuthResponse = function(token, effect) { 
    var authResponse = {}; 
    authResponse.isAuthenticated = true; 
    authResponse.principalId = 'TEST123'; 
    
    var policyDocument = {}; 
    policyDocument.Version = '2012-10-17';		 	 	 
    policyDocument.Statement = []; 
    var publishStatement = {}; 
    var connectStatement = {};
    connectStatement.Action = ["iot:Connect"];
    connectStatement.Effect = effect;
    connectStatement.Resource = ["arn:aws:iot:us-east-1:123456789012:client/myClientName"];
    publishStatement.Action = ["iot:Publish"]; 
    publishStatement.Effect = effect; 
    publishStatement.Resource = ["arn:aws:iot:us-east-1:123456789012:topic/telemetry/myClientName"]; 
    policyDocument.Statement[0] = connectStatement;
    policyDocument.Statement[1] = publishStatement; 
    authResponse.policyDocuments = [policyDocument]; 
    authResponse.disconnectAfterInSeconds = 3600; 
    authResponse.refreshAfterInSeconds = 300;
    
    return authResponse; 
}
```

 앞의 Lambda 함수는 MQTT Connect 메시지에서 `test`의 예상 암호를 수신하면 다음 JSON 값을 반환합니다. `password` 및 `principalId` 속성의 값은 MQTT Connect 메시지의 값이 됩니다.

```
{
  "password": "password",
  "isAuthenticated": true,
  "principalId": "principalId",
  "policyDocuments": [
    {
      "Version": "2012-10-17",		 	 	 
      "Statement": [
        {
          "Action": "iot:Connect",
          "Effect": "Allow",
          "Resource": "*"
        },
        {
          "Action": "iot:Publish",
          "Effect": "Allow",
          "Resource": "arn:aws:iot:region:accountId:topic/telemetry/${iot:ClientId}"
        },
        {
          "Action": "iot:Subscribe",
          "Effect": "Allow",
          "Resource": "arn:aws:iot:region:accountId:topicfilter/telemetry/${iot:ClientId}"
        },
        {
          "Action": "iot:Receive",
          "Effect": "Allow",
          "Resource": "arn:aws:iot:region:accountId:topic/telemetry/${iot:ClientId}"
        }
      ]
    }
  ],
  "disconnectAfterInSeconds": 3600,
  "refreshAfterInSeconds": 300
}
```

# 권한 부여자 생성
<a name="custom-auth-create-authorizer"></a>

 [CreateAuthorizer API](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateAuthorizer.html)를 사용하여 권한 부여자를 생성할 수 있습니다. 다음 예에서는 이 명령에 대해 설명합니다.

```
aws iot create-authorizer
--authorizer-name MyAuthorizer
--authorizer-function-arn arn:aws:lambda:us-west-2:<account_id>:function:MyAuthorizerFunction  //The ARN of the Lambda function.
[--token-key-name MyAuthorizerToken //The key used to extract the token from headers.
[--token-signing-public-keys FirstKey=
 "-----BEGIN PUBLIC KEY-----
  [...insert your public key here...] 
  -----END PUBLIC KEY-----"
[--status ACTIVE]
[--tags <value>]
[--signing-disabled | --no-signing-disabled]
```

`signing-disabled` 파라미터를 사용하여 권한 부여자를 호출할 때마다 서명 유효성 검사를 옵트아웃합니다. 필요한 경우가 아니면 서명을 비활성화하지 않는 것이 좋습니다. 서명 유효성 검사는 알 수 없는 디바이스에서 Lambda 함수를 과도하게 호출하지 않도록 보호합니다. 생성한 후에는 권한 부여자의 `signing-disabled` 상태를 업데이트 할 수 없습니다. 이 동작을 변경하려면 `signing-disabled` 파라미터에 대해 또 다른 값의 사용자 지정 권한 부여자를 생성해야 합니다.

`tokenKeyName` 및 `tokenSigningPublicKeys` 파라미터의 값은 서명을 사용하지 않도록 설정한 경우 선택 사항입니다. 서명이 활성화된 경우 필수 값입니다.

Lambda 함수와 사용자 지정 권한 부여자를 생성한 후에는 사용자를 대신하여 함수를 호출할 수 있는 AWS IoT Core 서비스 권한을 명시적으로 부여해야 합니다. 다음 명령을 사용하여이 작업을 수행할 수 있습니다.

**참고**  
기본 IoT 엔드포인트는 Lambda 함수와 함께 사용자 지정 권한 부여자를 사용하도록 지원하지 않을 수 있습니다. 그 대신, 도메인 구성을 사용하여 새 엔드포인트를 정의한 다음, 사용자 지정 권한 부여자에 대해 해당 엔드포인트를 지정할 수 있습니다.

```
aws lambda add-permission --function-name <lambda_function_name>
--principal iot.amazonaws.com --source-arn <authorizer_arn>
--statement-id Id-123 --action "lambda:InvokeFunction"
```

# Lambda 함수 AWS IoT 호출 권한 부여
<a name="custom-auth-authorize"></a>

이 섹션에서는 방금 생성한 사용자 지정 권한 부여자 리소스에 Lambda 함수를 실행할 수 있는 권한을 부여합니다. 권한을 부여하려면 [add-permission](https://docs.aws.amazon.com//cli/latest/reference/lambda/add-permission.html) CLI 명령을 사용할 수 있습니다.

**를 사용하여 Lambda 함수에 권한 부여 AWS CLI**

1. 값을 삽입한 후 다음 명령을 입력합니다. 참고: `statement-id` 값은 고유해야 합니다. `Id-1234`을(를) 정확한 값으로 바꿉니다. 그렇지 않으면 `ResourceConflictException` 오류가 발생할 수 있습니다.

   ```
   aws lambda add-permission  \
   --function-name "custom-auth-function" \
   --principal "iot.amazonaws.com" \
   --action "lambda:InvokeFunction" \
   --statement-id "Id-1234" \
   --source-arn authorizerArn
   ```

1. 명령이 성공하면 이 예제와 같은 권한 문이 반환됩니다. 다음 단원을 계속하여 사용자 지정 권한 부여자를 테스트할 수 있습니다.

   ```
   {
       "Statement": "{\"Sid\":\"Id-1234\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"iot.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function\"}}}"
   }
   ```

   명령이 성공하지 못하면 이 예제와 같은 오류가 반환됩니다. 계속하기 전에 오류를 검토하고 수정해야 합니다.

   ```
   An error occurred (AccessDeniedException) when calling the AddPermission operation: User: arn:aws:iam::57EXAMPLE833:user/EXAMPLE-1 is not authorized to perform: lambda:AddPer
   mission on resource: arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function
   ```

# 권한 부여자 테스트
<a name="custom-auth-testing"></a>

 [TestInvokeAuthorizer](https://docs.aws.amazon.com/iot/latest/apireference/API_TestInvokeAuthorizer.html) API를 사용하여 권한 부여자의 호출 및 반환 값을 테스트합니다. 이 API를 사용하면 권한 부여자에서 프로토콜 메타데이터를 지정하고 서명 유효성 검사를 테스트할 수 있습니다.

다음 탭은를 사용하여 권한 부여자를 테스트 AWS CLI 하는 방법을 보여줍니다.

------
#### [ Unix-like ]

```
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER \
--token TOKEN_VALUE --token-signature TOKEN_SIGNATURE
```

------
#### [ Windows CMD ]

```
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER ^
--token TOKEN_VALUE --token-signature TOKEN_SIGNATURE
```

------
#### [ Windows PowerShell ]

```
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER `
--token TOKEN_VALUE --token-signature TOKEN_SIGNATURE
```

------

`token-signature` 파라미터의 값은 서명된 토큰입니다. 이 값을 얻는 방법을 알아보려면 [토큰에 서명하기](custom-auth.md#custom-auth-token-signature) 단원을 참조하세요.

권한 부여자가 사용자 이름과 암호를 얻은 경우 `--mqtt-context` 파라미터를 사용하여 이 정보를 전달할 수 있습니다. 다음 탭은 `TestInvokeAuthorizer` API를 사용하여 사용자 이름, 암호 및 클라이언트 이름이 포함된 JSON 객체를 사용자 지정 권한 부여자에게 전송하는 방법을 보여줍니다.

------
#### [ Unix-like ]

```
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER  \
--mqtt-context '{"username": "USER_NAME", "password": "dGVzdA==", "clientId":"CLIENT_NAME"}'
```

------
#### [ Windows CMD ]

```
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER  ^
--mqtt-context '{"username": "USER_NAME", "password": "dGVzdA==", "clientId":"CLIENT_NAME"}'
```

------
#### [ Windows PowerShell ]

```
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER  `
--mqtt-context '{"username": "USER_NAME", "password": "dGVzdA==", "clientId":"CLIENT_NAME"}'
```

------

암호는 base64 인코딩해야 합니다. 다음 예제에서는 Unix 계열 환경에서 암호를 인코딩하는 방법을 보여 줍니다.

```
echo -n PASSWORD | base64
```

# 사용자 지정 권한 부여자 관리
<a name="custom-auth-manage"></a>

 다음 API를 사용하여 권한 부여자를 관리할 수 있습니다.
+ [ListAuthorizers](https://docs.aws.amazon.com/iot/latest/apireference/API_ListAuthorizers.html): 계정에 속한 모든 권한 부여자를 표시합니다.
+  [DescribeAuthorizer](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeAuthorizer.html): 지정한 권한 부여자의 속성을 표시합니다. 이러한 값에는 생성 날짜, 마지막 수정 날짜 및 기타 속성이 포함됩니다.
+ [SetDefaultAuthorizer](https://docs.aws.amazon.com/iot/latest/apireference/API_SetDefaultAuthorizer.html): AWS IoT Core 데이터 엔드포인트의 기본 권한 부여자를 지정합니다. 디바이스가 AWS IoT Core 자격 증명을 전달하지 않고 권한 부여자를 지정하지 않은 경우이 권한 부여자를 AWS IoT Core 사용합니다. 자격 AWS IoT Core 증명 사용에 대한 자세한 내용은 섹션을 참조하세요[클라이언트 인증](client-authentication.md).
+ [UpdateAuthorizer](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateAuthorizer.html): 지정된 권한 부여자의 상태, 토큰 키 이름 또는 퍼블릭 키를 변경합니다.
+  [DeleteAuthorizer](https://docs.aws.amazon.com/iot/latest/apireference/API_DeleteAuthorizer.html): 지정된 권한 부여자를 삭제합니다.

**참고**  
 권한 부여자의 서명 요구 사항은 업데이트할 수 없습니다. 즉, 필요한 기존 권한 부여자에서 로그인을 비활성화할 수 없습니다. 또한 필요하지 않은 기존 권한 부여자에는 로그인을 요구할 수 없습니다.

# X.509 클라이언트 인증서를 사용한 사용자 지정 인증
<a name="custom-auth-509cert"></a>

디바이스를 연결할 때 AWS IoT Core여러 [인증 유형을](protocols.md#connection-protocol-auth-mode) 사용할 수 있습니다. 클라이언트 및 디바이스 연결을 인증하는 데 사용할 수 있는 [X.509 클라이언트 인증서](https://docs.aws.amazon.com//iot/latest/developerguide/x509-client-certs.html)를 사용하거나 사용자 [지정 권한 부여자](https://docs.aws.amazon.com//iot/latest/developerguide/custom-authentication.html)를 정의하여 자체 클라이언트 인증 및 권한 부여 로직을 관리할 수 있습니다. 이 주제에서는 X.509 클라이언트 인증서와 함께 사용자 지정 인증을 사용하는 방법을 다룹니다.

X.509 인증서를 사용하여 디바이스를 이미 인증하고 추가 검증 및 사용자 지정 인증을 수행하려는 경우 X.509 인증서를 사용하여 사용자 지정 인증을 사용하는 것이 도움이 될 수 있습니다. 예를 들어 X.509 클라이언트 인증서에 일련 번호와 같은 디바이스의 데이터를 저장하는 경우 X.509 클라이언트 인증서를 AWS IoT Core 인증한 후 사용자 지정 권한 부여자를 사용하여 인증서의 CommonName 필드에 저장된 정보를 기반으로 특정 디바이스를 식별할 수 있습니다. X.509 인증서와 함께 사용자 지정 인증을 사용하면 디바이스를에 연결할 때 디바이스 보안 관리를 개선하고 인증 및 권한 부여 로직을 보다 유연하게 관리할 수 있습니다. AWS IoT Core 는 X.509 인증서 및 [MQTT](https://docs.aws.amazon.com//iot/latest/developerguide/mqtt.html) 프로토콜과 [HTTPS](https://docs.aws.amazon.com//iot/latest/developerguide/http.html) 프로토콜 모두에서 작동하는 사용자 지정 권한 부여자 인증 유형을 사용하여 X.509 인증서를 사용한 사용자 지정 인증을 AWS IoT Core 지원합니다. AWS IoT Core 디바이스 엔드포인트가 지원하는 인증 유형 및 애플리케이션 프로토콜에 대한 자세한 내용은 [Device communication protocols](https://docs.aws.amazon.com//iot/latest/developerguide/protocols.html) 섹션을 참조하세요.

**참고**  
X.509 클라이언트 인증서를 사용한 사용자 지정 인증은 AWS GovCloud (US) 리전에서 지원되지 않습니다.

**중요**  
[도메인 구성](iot-custom-endpoints-configurable.md) 을 사용하여 생성된 엔드포인트를 사용해야 합니다. 또한 클라이언트는 연결할 때 [서버 이름 표시(SNI)](https://www.rfc-editor.org/rfc/rfc3546#section-3.1) 확장을 제공해야 합니다 AWS IoT Core.

**Topics**
+ [1단계:에 X.509 클라이언트 인증서 등록 AWS IoT Core](#custom-auth-509cert-client)
+ [2단계: Lambda 함수 생성](#custom-auth-509cert-lambda)
+ [3단계: 사용자 지정 권한 부여자 생성](#custom-auth-509cert-authorizer)
+ [4단계: 도메인 구성에서 인증 유형 및 애플리케이션 프로토콜 설정](#custom-auth-509cert-domainconfig)

## 1단계:에 X.509 클라이언트 인증서 등록 AWS IoT Core
<a name="custom-auth-509cert-client"></a>

아직 등록하지 않은 경우에 [X.509 클라이언트 인증서를](https://docs.aws.amazon.com//iot/latest/developerguide/x509-client-certs.html) 등록하고 활성화합니다 AWS IoT Core. 그렇지 않은 경우 다음 단계로 건너뜁니다.

에 클라이언트 인증서를 등록하고 활성화하려면 다음 단계를 AWS IoT Core따릅니다.

1. [를 사용하여 직접 클라이언트 인증서를 생성하는 AWS IoT](https://docs.aws.amazon.com//iot/latest/developerguide/device-certs-create.html) 경우. 이러한 클라이언트 인증서는에 자동으로 등록됩니다 AWS IoT Core.

1. [자체 클라이언트 인증서를 생성하는](https://docs.aws.amazon.com//iot/latest/developerguide/device-certs-your-own.html) 경우 [다음 지침에 따라 인증서를 등록합니다 AWS IoT Core](https://docs.aws.amazon.com//iot/latest/developerguide/register-device-cert.html).

1. 클라이언트 인증서를 활성화하려면 [다음 지침](https://docs.aws.amazon.com//iot/latest/developerguide/activate-or-deactivate-device-cert.html)을 따르세요.

## 2단계: Lambda 함수 생성
<a name="custom-auth-509cert-lambda"></a>

AWS IoT Core 는 사용자 지정 권한 부여자를 사용하여 사용자 지정 인증 및 권한 부여 체계를 구현합니다. 사용자 지정 권한 부여자는 디바이스가 인증되었는지 여부와 디바이스가 수행할 수 있는 작업을 결정하는 Lambda 함수와 연결됩니다. 디바이스가에 연결되면 권한 부여자 이름 및 연결된 Lambda 함수를 포함한 권한 부여자 세부 정보를 AWS IoT Core AWS IoT Core 검색하고 Lambda 함수를 호출합니다. Lambda 함수는 디바이스의 X.509 클라이언트 인증서 데이터가 포함된 JSON 객체가 포함된 이벤트를 수신합니다. Lambda 함수는 이 이벤트 JSON 객체를 사용하여 인증 요청을 평가하고 수행할 작업을 결정한 다음 응답을 다시 보냅니다.

### Lambda 함수 이벤트 예제
<a name="custom-auth-509cert-event"></a>

다음 예제 JSON 객체에는 포함할 수 있는 모든 필드가 포함되어 있습니다. 실제 JSON 객체에는 특정 연결 요청과 관련된 필드만 포함됩니다.

```
{
	"token": "aToken",
	"signatureVerified": true,
	"protocols": [
		"tls",
		"mqtt"
	],
	"protocolData": {
		"tls": {
			"serverName": "serverName",
			"x509CertificatePem": "x509CertificatePem",
			"principalId": "principalId"
		},
		"mqtt": {
			"clientId": "myClientId",
                     "username": "myUserName",
                     "password": "myPassword"
		}
	},
	"connectionMetadata": {
		"id": "UUID"
	}
}
```

`signatureVerified`  
권한 부여자의 Lambda 함수를 호출하기 전에 권한 부여자에 구성된 토큰 서명이 확인되는지 여부를 나타내는 부울 값입니다. 권한 부여자가 토큰 서명을 비활성화하도록 구성된 경우 이 필드는 거짓입니다.

`protocols`  
요청에 대해 예상할 프로토콜이 포함된 배열입니다.

`protocolData`  
연결에 사용되는 프로토콜의 정보가 포함된 객체입니다. 인증, 권한 부여 등에 유용할 수 있는 프로토콜별 세부 정보를 제공합니다.  
`tls` - 이 객체는 TLS(Transport Layer Security) 프로토콜과 관련된 정보를 보유합니다.  
+ `serverName` - [서버 이름 표시(SNI)](https://www.rfc-editor.org/rfc/rfc3546#section-3.1) 호스트 이름 스트링입니다. AWS IoT Core 는 디바이스가 [SNI 확장](https://www.rfc-editor.org/rfc/rfc3546#section-3.1)을 Transport Layer Security(TLS) 프로토콜로 전송하고 `host_name` 필드에 전체 엔드포인트 주소를 제공하도록 요구합니다.
+ `x509CertificatePem` - TLS 연결에서 클라이언트 인증에 사용되는 PEM 형식의 X.509 인증서입니다.
+ `principalId` - TLS 연결에서 클라이언트와 연결된 위탁자 식별자입니다.
`mqtt` - 이 객체에는 MQTT 프로토콜과 관련된 정보가 들어 있습니다.  
+ `clientId` - 디바이스가 이 값을 보내는 경우에만 문자열을 포함해야 합니다.
+ `username` - MQTT Connect 패킷에 제공된 사용자 이름입니다.
+ `password` - MQTT Connect 패킷에 제공된 암호입니다.

`connectionMetadata`  
연결의 메타데이터입니다.  
`id` - 로깅 및 문제 해결에 사용할 수 있는 연결 ID입니다.

**참고**  
이 경우 JSON 객체 `x509CertificatePem` 및 `principalId`는 요청의 두 가지 새 필드입니다. `principalId`의 값은 `certificateId`의 값과 동일합니다. 자세한 내용은 [인증서](https://docs.aws.amazon.com//iot/latest/apireference/API_Certificate.html)를 참조하세요.

### Lambda 함수 응답 예제
<a name="custom-auth-509cert-response"></a>

Lambda 함수는 이벤트 JSON 객체의 정보를 사용하여 수신 연결을 인증하고 연결에서 허용되는 작업을 결정해야 합니다.

다음 JSON 객체에는 Lambda 함수가 전송할 수 있는 응답의 예가 들어 있습니다.

```
{
	"isAuthenticated": true,
	"principalId": "xxxxxxxx",
	"disconnectAfterInSeconds": 86400,
	"refreshAfterInSeconds": 300,
	"policyDocuments": [
		{
			"Version": "2012-10-17",		 	 	 
			"Statement": [
				{
					"Effect": "Allow",
					"Action": "iot:Publish",
					"Resource": "arn:aws:iot:us-east-1:123456789012:topic/customauthtesting"
				}
			]
		}
	]
}
```

이 예제에서는 이 함수가 다음 값을 포함하는 응답을 보내야 합니다.

`isAuthenticated`  
요청 인증 여부를 나타내는 부울 값입니다.

`principalId`  
사용자 지정 권한 부여 요청에서 전송되는 토큰의 식별자 역할을 하는 영숫자 문자열입니다. 값은 반드시 1\$1128개 글자의 영숫자 문자열이어야 합니다. 로그에서 연결을 식별합니다. `principalId` 값은 이벤트 JSON 객체(즉, X.509 인증서의 certificateId)의 `principalId` 값과 동일해야 합니다.

`policyDocuments`  
JSON 형식의 AWS IoT Core 정책 문서 목록입니다. 값은 선택 사항이며 [사물 정책 변수](https://docs.aws.amazon.com//iot/latest/developerguide/thing-policy-variables.html) 및 [인증서 정책 변수](https://docs.aws.amazon.com//iot/latest/developerguide/cert-policy-variables.html)를 지원합니다. 정책 문서의 최대 수는 10개입니다. 각 정책 문서는 최대 2,048자를 포함할 수 있습니다. 클라이언트 인증서와 Lambda 함수에 여러 정책이 연결되어 있는 경우 권한은 모든 정책의 모음입니다. AWS IoT Core 정책 생성에 대한 자세한 내용은 [정책을](https://docs.aws.amazon.com//iot/latest/developerguide/iot-policies.html) 참조하세요.

`disconnectAfterInSeconds`  
 AWS IoT Core 게이트웨이에 대한 연결의 최대 지속 시간(초)을 지정하는 정수입니다. 최솟값은 300초이고 최댓값은 86,400초입니다. `disconnectAfterInSeconds`는 연결 수명 동안 사용되며 연속 정책 새로 고침 시 새로 고쳐지지 않습니다.

`refreshAfterInSeconds`  
정책 새로 고침 사이의 간격을 지정하는 정수입니다. 이 간격이 경과하면가 Lambda 함수를 AWS IoT Core 호출하여 정책 새로 고침을 허용합니다. 최소값은 300초이고 최대값은 86,400초입니다.

### Lambda 함수 예제
<a name="custom-auth-509cert-js-example"></a>

다음은 샘플 Node.js Lambda 함수입니다. 이 함수는 클라이언트의 X.509 인증서를 검사하고 일련 번호, 지문 및 주제 이름과 같은 관련 정보를 추출합니다. 추출된 정보가 예상 값과 일치하면 클라이언트에 연결할 수 있는 액세스 권한이 부여됩니다. 이 메커니즘은 유효한 인증서가 있는 승인된 클라이언트만 연결을 설정할 수 있도록 합니다.

```
const crypto = require('crypto');

exports.handler = async (event) => {
    
    // Extract the certificate PEM from the event
    const certPem = event.protocolData.tls.x509CertificatePem;
    
    // Parse the certificate using Node's crypto module
    const cert = new crypto.X509Certificate(certPem);
    
    var effect = "Deny";
    // Allow permissions only for a particular certificate serial, fingerprint, and subject
    if (cert.serialNumber === "7F8D2E4B9C1A5036DE8F7C4B2A91E5D80463BC9A1257" // This is a random serial
       && cert.fingerprint === "F2:9A:C4:1D:B5:E7:08:3F:6B:D0:4E:92:A7:C1:5B:8D:16:0F:E3:7A" // This is a random fingerprint
       && cert.subject === "allow.example.com") {
      effect = "Allow";
    }
    
    return generateAuthResponse(event.protocolData.tls.principalId, effect);
};


// Helper function to generate the authorization response.
function generateAuthResponse(principalId, effect) {
    const authResponse = {
        isAuthenticated: true,
        principalId,
        disconnectAfterInSeconds: 3600,
        refreshAfterInSeconds: 300,
        policyDocuments: [
          {
            Version: "2012-10-17",		 	 	 
            Statement: [
              {
                Action: ["iot:Connect"],
                Effect: effect,
                Resource: [
                  "arn:aws:iot:us-east-1:123456789012:client/myClientName"
                ]
              },
              {
                Action: ["iot:Publish"],
                Effect: effect,
                Resource: [
                  "arn:aws:iot:us-east-1:123456789012:topic/telemetry/myClientName"
                ]
              },
              {
                Action: ["iot:Subscribe"],
                Effect: effect,
                Resource: [
                   "arn:aws:iot:us-east-1:123456789012:topicfilter/telemetry/myClientName"
                ]
              },
              {
                Action: ["iot:Receive"],
                Effect: effect,
                Resource: [
                   "arn:aws:iot:us-east-1:123456789012:topic/telemetry/myClientName"
                ]
              }
            ]
          }
        ]
      };

  return authResponse;
}
```

이전 Lambda 함수는 예상 직렬, 지문 및 제목이 포함된 인증서를 수신하면 다음 JSON을 반환합니다. `x509CertificatePem`의 값은 TLS 핸드셰이크에 제공된 클라이언트 인증서입니다. 자세한 내용은 [Defining your Lambda function](https://docs.aws.amazon.com//iot/latest/developerguide/config-custom-auth.html#custom-auth-lambda)을 참조하세요.

```
{
	"isAuthenticated": true,
	"principalId": "principalId in the event JSON object",
	"policyDocuments": [
		{
			"Version": "2012-10-17",		 	 	 
			"Statement": [
				{
					"Action": "iot:Connect",
					"Effect": "Allow",
					"Resource": "arn:aws:iot:us-east-1:123456789012:client/myClientName"
				},
				{
					"Action": "iot:Publish",
					"Effect": "Allow",
					"Resource": "arn:aws:iot:us-east-1:123456789012:topic/telemetry/myClientName"
				},
				{
					"Action": "iot:Subscribe",
					"Effect": "Allow",
					"Resource": "arn:aws:iot:us-east-1:123456789012:topicfilter/telemetry/myClientName"
				},
				{
					"Action": "iot:Receive",
					"Effect": "Allow",
					"Resource": "arn:aws:iot:us-east-1:123456789012:topic/telemetry/myClientName"
				}
			]
		}
	],
	"disconnectAfterInSeconds": 3600,
	"refreshAfterInSeconds": 300
}
```

## 3단계: 사용자 지정 권한 부여자 생성
<a name="custom-auth-509cert-authorizer"></a>

[Lambda 함수 를 정의](#custom-auth-509cert-lambda)한 후 사용자 지정 권한 부여자를 생성하여 자체 클라이언트 인증 및 권한 부여 로직을 관리합니다. [3단계: 사용자 지정 권한 부여자 리소스 생성 및 권한 부여](https://docs.aws.amazon.com//iot/latest/developerguide/custom-auth-tutorial.html#custom-auth-tutorial-authorizer)의 세부 지침을 따를 수 있습니다. 자세한 내용은 [권한 부여자 생성](https://docs.aws.amazon.com//iot/latest/developerguide/config-custom-auth.html)을 참조하세요.

사용자 지정 권한 부여자를 생성하는 과정에서 Lambda 함수를 생성한 후 이를 호출할 수 있는 AWS IoT 권한을 부여해야 합니다. 자세한 지침은 [Lambda 함수 호출 권한 부여 AWS IoT 를 참조하세요](custom-auth-authorize.md).

## 4단계: 도메인 구성에서 인증 유형 및 애플리케이션 프로토콜 설정
<a name="custom-auth-509cert-domainconfig"></a>

X.509 클라이언트 인증서로 사용자 지정 인증을 사용하여 디바이스를 인증하려면 도메인 구성에서 인증 유형 및 애플리케이션 프로토콜을 설정하고 SNI 확장을 전송해야 합니다. `authenticationType`의 값은 `CUSTOM_AUTH_X509`이어야 하며, `applicationProtocol`의 값은 `SECURE_MQTT` 또는 `HTTPS`일 수 있습니다.

### 도메인 구성에서 인증 유형 및 애플리케이션 프로토콜 설정(CLI)
<a name="custom-auth-509cert-cli"></a>

도메인 구성이 없는 경우 [https://docs.aws.amazon.com//cli/latest/reference/iot/create-domain-configuration.html](https://docs.aws.amazon.com//cli/latest/reference/iot/create-domain-configuration.html) 명령을 사용하여 생성합니다. `authenticationType`의 값은 `CUSTOM_AUTH_X509`이어야 하며, `applicationProtocol`의 값은 `SECURE_MQTT` 또는 `HTTPS`일 수 있습니다.

```
aws iot create-domain-configuration \
    --domain-configuration-name domainConfigurationName \
    --authentication-type CUSTOM_AUTH_X509 \  
    --application-protocol SECURE_MQTT \ 
    --authorizer-config '{
        "defaultAuthorizerName": my-custom-authorizer
    }'
```

도메인 구성이 이미 있는 경우 필요한 경우 [https://docs.aws.amazon.com//cli/latest/reference/iot/update-domain-configuration.html](https://docs.aws.amazon.com//cli/latest/reference/iot/update-domain-configuration.html) 명령 업데이트 `authenticationType` 및 `applicationProtocol`를 사용합니다. 기본 엔드포인트`iot:Data-ATS`()에서는 인증 유형 또는 프로토콜을 변경할 수 없습니다.

```
aws iot update-domain-configuration \
    --domain-configuration-name domainConfigurationName \
    --authentication-type CUSTOM_AUTH_X509 \  
    --application-protocol SECURE_MQTT \
    --authorizer-config '{
        "defaultAuthorizerName": my-custom-authorizer
    }'
```

`domain-configuration-name`  
도메인 구성의 이름입니다.

`authentication-type`  
도메인 구성의 인증 유형입니다. 자세한 내용은 [인증 유형 선택](protocols.md#connection-protocol-auth-mode)을 참조하세요.

`application-protocol`  
 AWS IoT Core와 통신하는 데 사용하는 디바이스의 애플리케이션 프로토콜입니다. 자세한 내용은 [애플리케이션 프로토콜 선택](protocols.md#protocol-selection)을 참조하세요.

`--authorizer-config`  
도메인 구성에서 권한 부여자 구성을 지정하는 객체입니다.

`defaultAuthorizerName`  
도메인 구성에 대한 권한 부여자의 이름입니다.

자세한 내용은 *AWS IoT API 참조*의 [CreateDomainConfiguration](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateDomainConfiguration.html) 및 [UpdateDomainConfiguration](https://docs.aws.amazon.com//iot/latest/apireference/API_UpdateDomainConfiguration.html)을 참조하세요. 도메인 구성에 대한 자세한 내용은 [Domain configurations](https://docs.aws.amazon.com//iot/latest/developerguide/iot-custom-endpoints-configurable.html)를 참조하세요.

# 사용자 지정 인증을 사용하여 AWS IoT Core 에 연결
<a name="custom-auth"></a>

 디바이스는 AWS IoT Core 에서 디바이스 메시징을 AWS IoT Core 지원하는 모든 프로토콜에서 사용자 지정 인증을 사용하여에 연결할 수 있습니다. 지원되는 통신 프로토콜에 대한 자세한 내용은 [디바이스 통신 프로토콜](protocols.md) 단원을 참조하세요.   권한 부여자 Lambda 함수에 전달하는 연결 데이터는 사용하는 프로토콜에 따라 다릅니다. 권한 부여자 Lambda 함수를 만드는 방법에 대한 자세한 내용은 [Lambda 함수 정의](custom-auth-lambda.md) 단원을 참조하세요. 다음 단원에서는 지원되는 각 프로토콜을 사용하여 인증에 연결하는 방법을 설명합니다.

## HTTPS
<a name="custom-auth-http"></a>

[HTTP 게시 API](https://docs.aws.amazon.com/iot/latest/apireference/API_iotdata_Publish.html)를 사용하여 AWS IoT Core 로 데이터를 전송하는 디바이스는 HTTP POST 요청의 요청 헤더 또는 쿼리 파라미터를 통해 자격 증명을 전달할 수 있습니다. 디바이스는 `x-amz-customauthorizer-name` 헤더 또는 쿼리 파라미터를 사용하여 호출할 권한 부여자를 지정할 수 있습니다. 권한 부여자에서 토큰 서명을 활성화한 경우 요청 헤더 또는 쿼리 파라미터 중 하나에서 `token-key-name` 및 `x-amz-customauthorizer-signature`을(를) 전달해야 합니다. 참고: 브라우저에서 JavaScript를 사용할 경우 `token-signature` 값은 URL로 인코딩해야 합니다.

**참고**  
HTTPS 프로토콜의 고객 권한 부여자는 게시 작업만 지원합니다. HTTPS 프로토콜에 대한 자세한 내용은 [디바이스 통신 프로토콜](protocols.md) 섹션을 참조하세요.

다음 예제 요청은 요청 헤더와 쿼리 파라미터 모두에서 이러한 파라미터를 전달하는 방법을 보여 줍니다.

```
//Passing credentials via headers
POST /topics/topic?qos=qos HTTP/1.1
Host: your-endpoint 
x-amz-customauthorizer-signature: token-signature
token-key-name: token-value 
x-amz-customauthorizer-name: authorizer-name

//Passing credentials via query parameters
POST /topics/topic?qos=qos&x-amz-customauthorizer-signature=token-signature&token-key-name=token-value HTTP/1.1
```

## MQTT
<a name="custom-auth-mqtt"></a>

 MQTT 연결을 사용하여 AWS IoT Core 에 연결하는 디바이스는 MQTT 메시지의 `username` 및 `password` 필드를 통해 자격 증명을 전달할 수 있습니다. `username` 값에는 추가 값(토큰, 서명 및 권한 부여자 이름 포함)을 권한 부여자에게 전달하는 쿼리 문자열이 선택적으로 포함될 수도 있습니다. `username` 및 `password` 값 대신 토큰 기반 인증 체계를 사용하려는 경우 이 쿼리 문자열을 사용할 수 있습니다.  

**참고**  
 암호 필드의 데이터는 base64로 인코딩됩니다 AWS IoT Core. 디코딩은 Lambda 함수로 해야 합니다.

 다음 예제는 토큰 및 서명을 지정하는 추가 파라미터가 포함된 `username` 문자열을 포함합니다.  

```
username?x-amz-customauthorizer-name=authorizer-name&x-amz-customauthorizer-signature=token-signature&token-key-name=token-value
```

권한 부여자를 호출하려면 MQTT 및 사용자 지정 인증을 사용하여 AWS IoT Core 에 연결하는 디바이스가 포트 443에서 연결되어야 합니다. 또한 값이 인 Application Layer Protocol Negotiation(ALPN) TLS 확장`mqtt`과 AWS IoT Core 데이터 엔드포인트의 호스트 이름이 있는 Server Name Indication(SNI) 확장을 전달해야 합니다. 잠재적 오류를 방지하기 위해 `x-amz-customauthorizer-signature` 값은 URL 인코딩을 해야 합니다. 또한 `x-amz-customauthorizer-name` 및 `token-key-name` 값을 URL 인코딩하는 것을 적극 권장합니다. 이러한 값에 대한 자세한 정보는 [디바이스 통신 프로토콜](protocols.md) 섹션을 참조하세요. V2 [AWS IoT 디바이스 SDK, 모바일 SDK 및 AWS IoT 디바이스 클라이언트](iot-sdks.md)는 이 두 확장을 모두 구성할 수 있습니다. 

## WebSocket을 통한 MQTT
<a name="custom-auth-websockets"></a>

 MQTT over WebSockets AWS IoT Core 을 사용하여에 연결하는 디바이스는 다음 두 가지 방법 중 하나로 자격 증명을 전달할 수 있습니다.
+ WebSockets 연결 설정을 위해 HTTP 업그레이드 요청의 요청 헤더 또는 쿼리 파라미터를 통해.
+ MQTT 연결 메시지의 `username` 및 `password` 필드를 통해.

 MQTT 연결 메시지를 통해 자격 증명을 전달하면 ALPN 및 SNI TLS 확장이 필요합니다. 이러한 확장에 대한 자세한 내용은 [MQTT](#custom-auth-mqtt) 단원을 참조하세요. 다음 예에서는 HTTP 업그레이드 요청을 통해 자격 증명을 전달하는 방법을 보여 줍니다.

```
GET /mqtt HTTP/1.1
Host: your-endpoint 
Upgrade: WebSocket 
Connection: Upgrade 
x-amz-customauthorizer-signature: token-signature
token-key-name: token-value 
sec-WebSocket-Key: any random base64 value 
sec-websocket-protocol: mqtt 
sec-WebSocket-Version: websocket version
```

## 토큰에 서명하기
<a name="custom-auth-token-signature"></a>

`create-authorizer` 호출에서 사용한 퍼블릭-프라이빗 키 페어의 프라이빗 키를 사용하여 토큰에 서명해야 합니다. 다음 예제에서는 UNIX 계열 명령과 JavaScript를 사용하여 토큰 서명을 생성하는 방법을 보여줍니다. 이들은 SHA-256 해시 알고리즘을 사용하여 서명을 인코딩합니다.

------
#### [ Command line ]

```
echo -n TOKEN_VALUE | openssl dgst -sha256 -sign PEM encoded RSA private key | openssl base64
```

------
#### [ JavaScript ]

```
const crypto = require('crypto')

const key = "PEM encoded RSA private key"

const k = crypto.createPrivateKey(key)
let sign = crypto.createSign('SHA256')
sign.write(t)
sign.end()
const s = sign.sign(k, 'base64')
```

------

# Lambda 권한 부여자 문제 해결
<a name="custom-auth-troubleshooting"></a>

 이 주제에서는 사용자 지정 인증 워크플로에서 문제를 일으킬 수 있는 일반적인 문제와 이를 해결하기 위한 단계를 안내합니다. 문제를 가장 효과적으로 해결하려면에 대해 CloudWatch 로그를 활성화 AWS IoT Core 하고 로그 수준을 **DEBUG**로 설정합니다. AWS IoT Core 콘솔([https://console.aws.amazon.com/iot/](https://console.aws.amazon.com/iot/))에서 CloudWatch 로그를 활성화할 수 있습니다. AWS IoT Core에 대해 로그를 활성화 및 구성하는 자세한 내용은 [AWS IoT 로깅 구성](configure-logging.md) 단원을 참조하세요.

**참고**  
로그 수준을 장기간 **디버그** 상태로 두면 CloudWatch에서 많은 양의 로깅 데이터를 저장할 것이고, 이렇게 하면 CloudWatch 요금이 증가할 수 있습니다. 특정 사물 그룹의 디바이스에 대해서만 상세도를 높이도록 리소스 기반 로깅을 사용하는 것이 좋습니다. 리소스 기반 로깅에 대한 자세한 내용은 [AWS IoT 로깅 구성](configure-logging.md) 단원을 참조하세요. 또한 문제 해결이 완료되면 로그 수준의 상세도를 낮추세요.

문제 해결을 시작하기 전에 사용자 지정 인증 프로세스를 자세히 볼 수 있도록 [사용자 지정 인증 워크플로 이해](custom-authorizer.md)을(를) 검토합니다. 이렇게 하면 문제의 원인을 찾을 위치를 파악하는 데 도움이 됩니다.

이 주제에서는 다음과 같은 두 가지 조사 영역에 대해 설명합니다.
+ 권한 부여자의 Lambda 함수와 관련된 문제.
+ 디바이스와 관련된 문제.

## 권한 부여자의 Lambda 함수에서 문제 확인
<a name="custom-auth-troubleshooting-lambda"></a>

장치의 연결 시도가 Lambda 함수를 호출하는지 확인하려면 다음 단계를 수행하세요.

1. 권한 부여자와 연결된 Lambda 함수를 확인합니다.

   [DescribeAuthorizer](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeAuthorizer.html) API를 호출하거나 AWS IoT Core 콘솔의 **보안** 단원에서 원하는 권한 부여자를 클릭하여 수행합니다.

1. Lambda 함수의 호출 지표를 확인합니다. 이렇게 하려면 다음 단계를 수행하세요.

   1.  AWS Lambda 콘솔([https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/))을 열고 권한 부여자와 연결된 함수를 선택합니다.

   1. **모니터링** 탭을 선택하고 문제와 관련된 시간 프레임에 대한 지표를 봅니다.

1. 호출이 표시되지 않으면 AWS IoT Core 에 Lambda 함수를 호출할 권한이 있는지 확인합니다. 호출이 표시되면 다음 단계로 건너뜁니다. Lambda 함수에 필요한 권한이 있는지 확인하려면 다음 단계를 수행하세요.

   1.  AWS Lambda 콘솔에서 함수에 대한 **권한** 탭을 선택합니다.

   1. 페이지 하단에서 **리소스 기반 정책** 단원을 찾습니다. Lambda 함수에 필요한 권한이 있는 경우 정책은 다음 예와 같습니다.  
****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Id": "default",
        "Statement": [
          {
            "Sid": "Id123",
            "Effect": "Allow",
            "Principal": {
              "Service": "iot.amazonaws.com"
            },
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:us-east-1:111111111111:function:FunctionName",
            "Condition": {
              "ArnLike": {
                "AWS:SourceArn": "arn:aws:iot:us-east-1:111111111111:authorizer/AuthorizerName"
              },
              "StringEquals": {
                "AWS:SourceAccount": "111111111111"
              }
            }
          }
        ]
      }
      ```

   1. 이 정책은 AWS IoT Core 보안 주체에게 함수에 대한 `InvokeFunction` 권한을 부여합니다. 표시되지 않으면 [AddPermission](https://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html) API를 사용하여 추가해야 합니다. 다음 예에서는 AWS CLI을(를) 사용하여 이 작업을 수행하는 방법을 보여줍니다. 

      ```
      aws lambda add-permission --function-name FunctionName --principal iot.amazonaws.com --source-arn AuthorizerARn --statement-id Id-123 --action "lambda:InvokeFunction"
      ```

1. 호출이 표시되면 오류가 없는지 확인합니다. 오류는 Lambda 함수가에서 AWS IoT Core 전송한 연결 이벤트를 제대로 처리하지 못하고 있음을 나타낼 수 있습니다.

   Lambda 함수에서 이벤트를 처리하는 방법에 대한 자세한 내용은 [Lambda 함수 정의](custom-auth-lambda.md) 단원을 참조하세요. AWS Lambda 콘솔([https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/))의 테스트 기능을 사용하여 함수의 테스트 값을 하드 코딩하여 함수가 이벤트를 올바르게 처리하고 있는지 확인할 수 있습니다.

1. 오류 없이 호출이 표시되지만 디바이스가 연결할 수 없거나 메시지를 게시, 구독 및 수신할 수 없는 경우 Lambda 함수가 반환하는 정책이 디바이스가 수행하려는 작업에 대한 권한을 부여하지 않는 문제일 수 있습니다. 함수가 반환하는 정책에 문제가 있는지 확인하려면 다음 단계를 수행하세요.

   1. Amazon CloudWatch Logs Insights 쿼리를 사용하여 짧은 기간 동안 로그를 스캔하여 실패를 확인합니다. 다음 예제 쿼리는 타임스탬프별로 이벤트를 정렬하고 실패를 찾습니다.

      ```
      display clientId, eventType, status, @timestamp | sort @timestamp desc | filter status = "Failure"    
      ```

   1. Lambda 함수를 업데이트하여 반환되는 데이터와 함수 AWS IoT Core 를 트리거하는 이벤트를 로깅합니다. 이러한 로그를 사용하여 함수가 만드는 정책을 검사할 수 있습니다.

1. 오류 없이 호출이 표시되지만 디바이스가 연결할 수 없거나 메시지를 게시, 구독 및 수신할 수 없는 경우 Lambda 함수가 제한 시간을 초과했기 때문일 수 있습니다. 사용자 지정 권한 부여자에 대한 Lambda 함수 제한 시간은 5초입니다. CloudWatch 로그 또는 지표에서 함수 기간을 확인할 수 있습니다.

## 디바이스 문제 조사
<a name="custom-auth-troubleshooting-investigate"></a>

Lambda 함수를 호출하거나 함수가 반환하는 정책에 문제가 없으면 디바이스의 연결 시도에 문제가 있는지 확인합니다. 잘못된 연결 요청으로 인해가 권한 부여자를 트리거 AWS IoT Core 하지 않을 수 있습니다. TLS 및 애플리케이션 계층 모두에서 연결 문제가 발생할 수 있습니다.

**가능한 TLS 계층 문제:**
+ 고객은 모든 사용자 지정 인증 요청에서 호스트 이름 헤더(HTTP, WebSockets을 통한 MQTT) 또는 서버 이름 표시 TLS 확장(HTTP, WebSockets을 통한 MQTT, MQTT)을 전달해야 합니다. 두 경우 모두 전달된 값은 계정의 AWS IoT Core 데이터 엔드포인트 중 하나와 일치해야 합니다. 이러한 엔드포인트는 다음 CLI 명령을 수행할 때 반환되는 엔드포인트입니다.
  + `aws iot describe-endpoint --endpoint-type iot:Data-ATS`
  + `aws iot describe-endpoint --endpoint-type iot:Data`(레거시 VeriSign 엔드포인트용)
+ MQTT 연결에서 사용자 지정 인증을 사용하는 디바이스가 `mqtt` 값의 ALPN(Application Layer Protocol Negotiation) TLS 확장을 전달해야 합니다.
+ 사용자 지정 인증은 현재 포트 443에서만 사용할 수 있습니다.

**가능한 애플리케이션 계층 문제:**
+ 서명이 활성화된 경우(`signingDisabled` 필드가 false인 경우) 다음 서명 문제를 찾습니다.
  + 토큰 서명을 `x-amz-customauthorizer-signature` 헤더 또는 쿼리 문자열 파라미터로 전달하고 있는지 확인합니다.
  + 서비스가 토큰이 아닌 다른 값에 서명하고 있지 않은지 확인합니다.
  + 권한 지정자의 `token-key-name` 필드에 지정한 헤더 또는 쿼리 파라미터로 토큰을 전달하는지 확인합니다.
+ `x-amz-customauthorizer-name` 헤더 또는 쿼리 문자열 파라미터로 전달한 권한 부여자 이름이 유효하거나 계정에 대해 기본 권한 부여자가 정의되어 있어야 합니다.