2016-10-18 52 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