我写了这段代码,但是我收到了一个错误。我怎么去上班? 但同样的道理也适用于邮递员。
错误:
{"message":"The security token included in the request is invalid."}
代码:
public class test extends AppCompatActivity {
private final AWS4Signer signer = new AWS4Signer();
Request<?> aws;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
AWSCredentials credentials = new BasicAWSCredentials("AccessKey", "SecretKey");
aws = generateBasicRequest();
signer.setServiceName("execute-api");
signer.sign(aws, credentials);
new get_aws().execute();
}
private Request<?> generateBasicRequest() {
Request<?> request = new DefaultRequest<Void>("execute-api");
request.addHeader("Content-type", "application/json");
String securityToken = "Session Token";
request.addHeader("X-Amz-Security-Token", securityToken);
request.addHeader("Host", "********.amazonaws.com");
request.addHeader("x-amz-archive-description", "test test");
request.setResourcePath("/");
request.setEndpoint(URI.create("https://******.execute-api.****.amazonaws.com/data/all"));
return request;
}
private class get_aws extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
BufferedReader in = null;
String data = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.addHeader("Authorization", aws.getHeaders().get("Authorization"));
request.addHeader("X-Amz-Date",request_aws.getHeaders().get("X-Amz-Date"));
request.addHeader("Content-Type","application/x-www-form-urlencoded");
URI website = new URI("https://********.execute-api.*******.amazonaws.com/data/all");
request.setURI(website);
HttpResponse response = httpclient.execute(request);
in = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line = in.readLine();
Log.d("line", line);
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
return null;
}
@Override
protected void onPostExecute(Void result) {
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
}
答案 0 :(得分:8)
要回答您的直接问题,AWS可以为您generate a Java SDK from your API Gateway。
使用生成的SDK,您可以将AWSCredentialsProvider
对象传递到SDK中。
AWSCredentials credentials = new BasicAWSCredentials("AccessKey", "SecretKey");
ApiClientFactory factory = new ApiClientFactory()
.credentialsProvider(credentials);
<强>可是... 强>
您不应该在发货的应用程序中发送IAM访问密钥。安装您的应用程序的任何人都可以通过打开.apk
文件来检索这些凭据。
然后,可以使用这些凭据访问关联的IAM用户在您的帐户中可以访问的任何其他AWS操作。这意味着任何有权访问应用程序apk的人(即:可以从应用程序商店下载应用程序的任何人)都可以访问您的AWS账户。
根据您要解决的问题,将决定解决问题的正确方法。
我的Lambda需要运行IAM角色
当人们在API网关中看到“使用来电者凭证调用”选项时,使用API网关时,这是一个相当常见的错误。
取消选中此框,Lambda将使用您在Lambda中定义的IAM角色运行。
如果执行此操作后请求失败,您需要确保API Gateway有权调用您的lambda。
在没有用户的情况下将API限制为应用程序本身
您的应用程序无法保密,您没有用户凭据。
您应该完全禁用授权,这实际上是一个公共API。
要求API密钥(和使用计划)对API进行速率限制可能很有用,但请记住,这不是一种安全措施,因为您的应用程序无法保密该密钥。
您希望用户首先登录(没有现有的用户来源)
如果您的API调用仅设计为由注册用户调用,则这是有意义的。
您需要为此配置Cognito用户池。这不应与Cognito Federated Identities混淆 - 后者侧重于问题的不同部分。你可以用它来解决这个问题,但请相信我 - 如果你不走这条路,你会更开心。
要破解你需要采取一些步骤:
Create an App Client for your pool。执行此操作时,请勿生成客户端密钥。
与您的Android应用程序集成。 AWS提供了一个预先构建的Android示例,用于让客户端进行:AmazonCognitoYourUserPoolsDemo
您希望用户首先登录(现有用户来源)
如果您可以使用SAML或OAuth2.0 / OpenID Connect对用户进行身份验证,请按照说明操作,然后configure federation。
如果没有,可能需要考虑Cognito Federated Identities,特别是使用Developer Authenticated Identities进程。但同样,我真的建议反对它。
API Gateway&amp; Cognito是一个很大的话题。希望所提供的说明是文档相关部分的重要切入点。
答案 1 :(得分:0)
如果您尝试查看具有认知凭证的AWS https://github.com/awslabs/aws-sdk-android-samples中的示例,我发现它们更易于使用,如果您想使用AccessKey和SecretKey,还可以使用类似的
AWSCredentials credentials = new BasicAWSCredentials("AccessKey", "SecretKey");
AmazonS3Client sS3Client = new AmazonS3Client(credentials,Region.getRegion("Region"));