2016-10-18 80 views
1

我正在創建一個使用Amazon Cognito身份驗證連接到AWS IoT的Android應用程序。我能夠成功驗證用戶,並且我能夠獲得憑據。 使用這些憑據更新事物影子時總是返回403禁止例外。我嘗試了所有方法來解決問題,但我找不到解決方案。使用Amazon Cognito訪問AWS Iot時的禁止例外

我的IAM策略是:

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
     { 
      "Effect": "Allow", 
      "Action": [ 
       "iot:GetThingShadow", 
       "iot:UpdateThingShadow", 

      ], 
      "Resource": [ 
       "arn:aws:iot:us-west-2:<my_account>:thing/mythingname" 
      ] 
     } 
    ] 
} 

連接端點的Android代碼:

userSession= AppHelper.getCurrSession(); 
credentialsProvider=new CognitoCachingCredentialsProvider(getApplicationContext(),POOL_ID,REGIONS); 

    Map<String,String> logins=new HashMap<String, String>(); 
    logins.put("cognito-idp.us-west-2.amazonaws.com/user_pool_id",userSession.getIdToken().getJWTToken()); 

    credentialsProvider.setLogins(logins); 
    iotDataClient=new AWSIotDataClient(credentialsProvider); 

    iotDataClient.setEndpoint(ENDPOINT); 

更新的東西的影子:

UpdateThingShadowRequest request=new UpdateThingShadowRequest(); 
      request.setThingName(thingName); 

      ByteBuffer payloadBuffer=ByteBuffer.wrap(updateState.getBytes()); 
      request.setPayload(payloadBuffer); 

      UpdateThingShadowResult result=iotDataClient.updateThingShadow(request); 

有這方面的任何幫助將不勝感激。

+0

這個IAM策略附加,已驗證或未驗證的角色是Cognit角色?您使用的是哪種身份驗證提供程序? –

+0

我正在使用身份驗證角色。作爲提供商,我使用身份池與用戶池集成 – Arun

回答

3

我和你有同樣的問題。我找到了一個解決方案。

403狀態碼錶示您需要授權。

如果您閱讀本文檔(接近尾聲):Publish/Subscribe Policy Exemple它表示您需要2策略以使其與Authenticated Cognito User一起使用。一個用於Cognito身份池,另一個用於Cognito用戶。

使用UI無法將策略附加到cognito用戶,但可以通過CLI執行此操作。

命令將策略附加到cognito用戶:

aws iot attach-principal-policy --principal "cognito user id" --policy-Name "policy name"

你可以找到你的cognito用戶ID在:

Cognito > Manager Federated Identities > choose your identity pool > identity browser > and find your identity ID

我用這個策略測試目的。

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

爲了使其可重用,您需要使用lambda函數(在JavaScript中)。

var AWS = require('aws-sdk'); 
var iot = new AWS.Iot(); 

exports.handler = function(event, context, cb) { 
    var params = { 
     policyName: 'your policy', 
     principal: 'your cognito id' 
    }; 

    var out = iot.attachPrincipalPolicy(params, function(err, data) { 
     if (err) cb(err); 
     else cb(null, data); 
    }); 
}; 
+0

感謝您的評論,這正是我需要做的!我有一個關於最後一步的問題(把它放在Lambda函數中)。是否有可以用來自動運行lambda的觸發器/事件? –

+0

@TurnerHoughton謝謝。找到這個解決方案有點困難,我很高興它爲你提供了幫助。對於你的問題,這取決於你想做什麼,對我來說,我在api網關中創建了一個名爲/ register的路徑,它將一個iot設備註冊到特定的用戶帳戶。 – Sapher

+0

您是否在前端有一些邏輯來確定您何時訪問該端點?或者你每次用戶登錄時都運行它?因爲它只需要每個用戶運行一次,對吧? –

0

我能夠確定問題。在我的情況下,我錯過了爲AWS iot客戶端設置region

Region region = Region.getRegion(MY_REGION); 
mIotAndroidClient.setRegion(region); // I was missing this piece of code