Как добавить подпись aws в android и вызвать aws api gateway

Я написал этот код, но получаю сообщение об ошибке. Как я могу работать? Но тот же самый токен работает с почтальоном.

Ошибка:

 {"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) {
        }
    }
}

Ответы

Ответ 1

Чтобы ответить на ваш вопрос, AWS может создать Java SDK из вашего шлюза API для вас.

Используя сгенерированный SDK, вы можете передать объект AWSCredentialsProvider в свой SDK.

         AWSCredentials credentials = new BasicAWSCredentials("AccessKey", "SecretKey");

ApiClientFactory factory = new ApiClientFactory()
  .credentialsProvider(credentials);

Но...

Вы не должны отправлять ключи доступа IAM в отправленное приложение. Эти учетные данные могут быть получены любым, кто установил ваше приложение, открыв файл .apk.

Эти учетные данные затем могут использоваться для доступа к любым другим действиям AWS, к которым у пользователя, имеющего доступ к IAM, имеется доступ к вашей учетной записи. Это означает, что любой пользователь, имеющий доступ к приложению apk (т.е. Любой, кто может загрузить приложение из магазина приложений), имеет доступ к вашей учетной записи AWS.

В зависимости от того, какую проблему вы пытаетесь решить, будет диктовать правильное решение проблемы.

Моя Лямбда нуждается в роли IAM для запуска

Это довольно распространенная ошибка, возникающая при использовании шлюза API, когда люди видят параметр "Invoke with caller credentials" из шлюза API.

Снимите этот флажок, и Lambda будет работать с ролью IAM, которую вы определили в Lambda.

Если запросы не выполняются после этого, вам необходимо убедиться, что API Gateway имеет разрешение на вызов вашей лямбда.

Ограничить API для самого приложения без пользователей

Ваше приложение не может хранить секрет, и у вас нет учетных данных пользователя.

Вы должны полностью отключить авторизацию, это фактически открытый API.

Требование использовать ключ API (и план использования) для ограничения скорости вашего API может быть полезным, но имейте в виду, что это не мера безопасности, поскольку снова - ваше приложение не может хранить этот секрет ключа.

Вы хотите, чтобы пользователи сначала регистрировались (нет существующего источника пользователей)

Это имеет смысл, если ваш вызов API предназначен только для вызова зарегистрированными пользователями.

Для этого вам необходимо настроить Cognito User Pools. Это не следует путать с Cognito Federated Identities, которая фокусируется на другой части проблемы. Вы можете использовать его для решения этой проблемы, но поверьте мне - вы будете счастливее, если не пойдет по этому пути.

Чтобы взломать, вам нужно сделать несколько шагов:

Вы хотите, чтобы пользователи сначала регистрировались (существующий источник пользователей)

Если вы можете использовать SAML или OAuth2.0/OpenID Connect для аутентификации ваших пользователей, следуйте инструкциям, а затем настроить федерацию.

Если нет, возможно, это время, чтобы рассмотреть Cognito Federated Identities, в частности, используя Разработчик Authenticated Identities. Но опять же, я бы рекомендовал против этого.

API Gateway и Cognito - это серьезная тема. Надеемся, что предоставленные инструкции являются отличной точкой входа в соответствующие части документации.