Reading AWS Amplify managed Storage vault (private S3 key) objects from Lambda

Viewed 315

I have a small Angular application in which I use AWS Amplify in conjunction with AWS Cognito User Pools to manage and authenticate users. I use AWS Amplify Storage API to store user data in S3.

I would like to have a Java AWS Lambda call that can assume the identity of a user and access the data stored in S3 bucket as if it was the web application the user logged into within the browser. The Lambda should be able to authenticate an incoming AWS API Gateway request originating from an authenticated browser session and map the authenticated user's identity and object key to the actual S3 location so that it can be loaded and processed before returning the result to the client.

On the client side, I simply use Auth from aws-amplify to authenticate.

import { Injectable } from '@angular/core';
import {Observable, throwError, from, BehaviorSubject} from 'rxjs';
import {Auth} from 'aws-amplify';

// ... lines omitted
import {CognitoUser} from 'amazon-cognito-identity-js';
// ... lines omitted

@Injectable({
  providedIn: 'root',
})
export class AccountService {

  // ... lines omitted
  authenticate(username: string, password: string): Observable<any> {
    return from(Auth.signIn(username, password));
  }
  // ... lines omitted
}

Then I have a thin wrapper around the Storage API of aws-amplify to store preferences.

// ... lines omitted
import {BehaviorSubject, from, Observable, of, throwError} from 'rxjs';
import {Storage} from 'aws-amplify';
// ... lines omitted

@Injectable({
  providedIn: 'root',
})
export class PreferencesService {

  // ... lines omitted
  private saveData(data: Data[]) {
    const dataAsJson: string = JSON.stringify(data);
    return from(Storage.vault.put('data.json', dataAsJson));
  }

  private getData(key: string) {
    return from(Storage.vault.get(key)).pipe(
      switchMap(dataUrl => {
        return this.http.get(dataUrl as string).pipe(
          map(it => {
            const data = it as Data[];
            return data;
          }),
          catchError(err => {

            if (err['status'] === 404) {
              // HTTP 404 is translated to empty result
              return of(null);
            } else {
              return throwError(err);
            }
          }));
      }));  

What I would like to do is:

  1. Authenticate an incoming API Gateway request in Lambda and assume the same identity within the Lambda function as the client browser session has so that I can only read the same set of data. (The lambda call can only read data.json for that particular user: obviously, each user has his/her data.json)
  2. Lookup the Amplify vault storage paths for the authenticated user ID and specified key, just like as if I was using the Amplify Storage.vault.get(key) API call. (The lambda call should be able to figure out the actual S3 location of data.json for that particular user)
0 Answers
Related