我有具有联合ID的经过身份验证的用户。但是,当我尝试访问AWS IOT东西时,出现此错误,这使我发疯。

我正在关注iot sample code。所有相关凭证也都是正确的。

    `MQTTHelper`
    ....
        credentialsProvider = new CognitoCachingCredentialsProvider(
                        mContext.getApplicationContext(), // context
                        BuildConfig.COGNITO_POOL_ID, // Identity Pool ID
                        MY_REGION // Region
                );

                Region region = Region.getRegion(MY_REGION);

                mqttManager = new AWSIotMqttManager(clientId, BuildConfig.CUSTOMER_SPECIFIC_ENDPOINT);
                mqttManager.setKeepAlive(10);
mAwsIotDataClient = new AWSIotDataClient(credentialsProvider);
        String iotDataEndpoint = BuildConfig.CUSTOMER_SPECIFIC_ENDPOINT;
        mAwsIotDataClient.setEndpoint(iotDataEndpoint);
        mAwsIotDataClient.setRegion(region);

        // mqttManager.setMqttLastWillAndTestament(lwt);

        mIotAndroidClient = new AWSIotClient(credentialsProvider);
        mIotAndroidClient.setRegion(region);

        keystorePath = mContext.getFilesDir().getPath();
        keystoreName = BuildConfig.KEYSTORE_NAME;
        keystorePassword = BuildConfig.KEYSTORE_PASSWORD;
        certificateId = BuildConfig.CERTIFICATE_ID;

        // To load cert/key from keystore on filesystem
        try {
            if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath, keystoreName)) {
                if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId, keystorePath,
                        keystoreName, keystorePassword)) {
                    Log.d(LOG_TAG, "Certificate " + certificateId
                            + " found in keystore - using for MQTT.");
                    // load keystore from file into memory to pass on connection
                    clientKeyStore = AWSIotKeystoreHelper.getIotKeystore(certificateId,
                            keystorePath, keystoreName, keystorePassword);
                    //btnConnect.setEnabled(true);
                    Log.i(LOG_TAG, "Connected....");
                    //CONNECTED_TO_DEVICE = true;
                } else {
                    Log.i(LOG_TAG, "Key/cert " + certificateId + " not found in keystore.");
                }
            } else {
                Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName + " not found.");
            }
        } catch (Exception e) {
            Log.e(LOG_TAG, "An error occurred retrieving cert/key from keystore.", e);
        }


        if (clientKeyStore == null) {

            IS_CERTIFICATE_GENERATED = false;

            Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new key and certificate.");

            doGenerateNewCertificate();

        } else {

            IS_CERTIFICATE_GENERATED = true;
            doMqttConnect();
        }




    }

    private static void doMqttConnect() {

        Log.d(LOG_TAG, "clientId = " + clientId);

        try {
            mqttManager.connect(clientKeyStore, new AWSIotMqttClientStatusCallback() {
                @Override
                public void onStatusChanged(final AWSIotMqttClientStatus status,
                                            final Throwable throwable) {
                    Log.d(LOG_TAG, "Status = " + String.valueOf(status));

                    if (mqttManagerConnStatus != null) {
                        //Send Mqtt Manager Status Back
                        mqttManagerConnStatus.onStatusChanged(status, throwable);
                    }


                }

            });
        } catch (final Exception e) {
            Log.e(LOG_TAG, "Connection error.", e);

        }


和示例代码中提到的类似,我在另一个类中调用GetShadow()

 GetThingShadowRequest getThingShadowRequest = new GetThingShadowRequest() .withThingName(thingName);

                GetThingShadowResult result = mDashboard.mqttHelper.doGetAwsIotDataClient()
                        .getThingShadow(getThingShadowRequest);

                byte[] bytes = new byte[result.getPayload().remaining()];
                result.getPayload().get(bytes);

                String resultString = new String(bytes);
                return new AsyncTaskResult<String>(resultString);


我能够使KMS工作,因此身份验证(联合ID)没有问题。我在AWS IOT上获得的唯一信息来源只是this,从客户端的角度来看这无济于事。
是AWS IOT配置问题还是代码问题?我必须订阅Thing Group,要订阅该组还有什么需要做的吗?
这是我需要订阅的Thing Group ARN
arn:aws:iot:us-east-1:XXXXXXXXXX:thinggroup/A_GROUP

堆栈跟踪

getShadowTask
    com.amazonaws.AmazonServiceException: null (Service: AWSIotData; Status Code: 403; Error Code: ForbiddenException; Request ID: f78eea4d-9053-4b19-1840-297dd67c2667)
        at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:730)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
        at com.amazonaws.services.iotdata.AWSIotDataClient.invoke(AWSIotDataClient.java:571)
        at com.amazonaws.services.iotdata.AWSIotDataClient.getThingShadow(AWSIotDataClient.java:406)
        at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:519)
        at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:497)
        at android.os.AsyncTask$2.call(AsyncTask.java:295)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)
06-18 06:00:54.029 7489-7489/com.lyrebird.abc E/com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter.GetShadowTask: getShadowTask
    com.amazonaws.AmazonServiceException: null (Service: AWSIotData; Status Code: 403; Error Code: ForbiddenException; Request ID: f78eea4d-9053-4b19-1840-297dd67c2667)
        at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:730)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:405)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:212)
        at com.amazonaws.services.iotdata.AWSIotDataClient.invoke(AWSIotDataClient.java:571)
        at com.amazonaws.services.iotdata.AWSIotDataClient.getThingShadow(AWSIotDataClient.java:406)
        at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:519)
        at com.lyrebird.abc.device.MyDevicesFragment_RV_Adapter$GetShadowTask.doInBackground(MyDevicesFragment_RV_Adapter.java:497)
        at android.os.AsyncTask$2.call(AsyncTask.java:295)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:818)


政策

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:*",
        "lambda:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

最佳答案

这是您可能会收到错误403的几个原因


在Cognito中,对于经过身份验证的池和未经身份验证的池都没有适当的更新/获取影子权限
Cognito池ID的ARN和IoT不正确
检查IAM策略和以下策略给Cognito用户,同样对于Cognito用户,您还必须附加AttachPrincipalPolicy策略,为他们提供适当的权限来获取/更新影子。以下策略应为Cognito Auth和UnAuth角色。

{

"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "iot:AttachPrincipalPolicy"
        ],
        "Resource": [
            "*"
        ]
    }
] }

关于android - 在AWS IOT中调用getShadow/updateShadow时出现ForbiddenError 403,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50848195/

10-11 16:19