1

I have an App engine application. I want to use Cloud Storage to store some user-uploaded files.

I want to know how to do simple authentication to access the single, free bucket that comes with every app engine application.

I want only the application itself to talk to Cloud storage, and the user need not have any interaction with Cloud storage. Every file can be placed in the same folder and it needs to be accessible only to the App engine JVM.

Is there a simple way for the authentication, without going through Oauth2 etc.? A simple server-to-server sort of access, if its possible!

Edit: Is it the same as this?

gcloud beta auth application-default login

Edit 2: Tried the above default authentication setup for Gcloud. Still the same exception is thrown.

com.google.cloud.storage.StorageException: Invalid Credentials

Testing code that I am using:

private static Storage storage = null;
static {
      storage = StorageOptions.getDefaultInstance().getService();
    }

@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    PrintWriter out = resp.getWriter();
    out.println("Hello, world");

    testCloudStorage();
}

private void testCloudStorage() throws IOException{
    ByteArrayInputStream baIs = new ByteArrayInputStream("TEST FILE CONTENT".getBytes());
    uploadFile("test-content.txt", baIs, "xyzabc.appspot.com");
}

/**
 * Uploads a file to Google Cloud Storage to the bucket specified in the BUCKET_NAME
 * environment variable, appending a timestamp to end of the uploaded filename.
 */
public String uploadFile(String fileName, InputStream inputStream, final String bucketName) throws IOException {
  DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
  DateTime dt = DateTime.now(DateTimeZone.UTC);
  String dtString = dt.toString(dtf);
  final String extendedFileName = fileName + dtString;

  // the inputstream is closed by default, so we don't need to close it here
  BlobInfo blobInfo =
      storage.create(
          BlobInfo
              .newBuilder(bucketName, extendedFileName)
              // Modify access list to allow all users with link to read file
              .setAcl(new ArrayList<>(Arrays.asList(Acl.of(Acl.User.ofAllUsers(), Role.READER))))
              .build(),
          inputStream);
  // return the public download link
  return blobInfo.getMediaLink();
}

Edit 3: These are the steps I followed:

  1. I have a basic working JSP sample application - both devserver and deployed version are working okay
  2. DataStore is working - insert/update/delete
  3. I added the sample code for Cloud Storage following this tutorial
  4. I followed this tutorial for installing GCloud SDK and doing init and setting the default auth
Teddy
  • 4,009
  • 2
  • 33
  • 55
  • show us what you tried based on the official docs. – Zig Mandel Feb 04 '17 at 13:22
  • @ZigMandel I have a JSP application running on app engine already. I have created a test servlet to test cloud storage. I just want to write a few bytes to a test file. I added the servlet code in the question now. – Teddy Feb 04 '17 at 13:24

1 Answers1

1

Appengine projects are already authenticated with their respective buckets. There is no additional authentication needed - once the bucket is created as per https://cloud.google.com/appengine/docs/java/googlecloudstorageclient/setting-up-cloud-storage .

You can then use the bucket as per those docs or blobstore https://cloud.google.com/appengine/docs/java/blobstore/ .

Aaron
  • 801
  • 1
  • 7
  • 12
  • I went through your first link. It could be that the problem is accessing from local deployment. I start the project from maven like this: mvn appengine:devserver Where can I add this flag? --default_gcs_bucket_name [BUCKET_NAME] – Teddy Feb 04 '17 at 14:57
  • Thanks for that! When I deploy to cloud, the access is working automatically. Now the problem is only with the development environment. – Teddy Feb 04 '17 at 15:01
  • I tried this... but that didn't work either: mvn appengine:devserver -Ddefault_gcs_bucket_name=abcxyz.appsopt.com – Teddy Feb 04 '17 at 15:10
  • Are you doing this for testing - i.e. testing your code works for putting data in gcs, or are you trying to access the live data in gcs for local testing? The former should just work - you don't need to access real gcs for local testing. The latter is a bit more tricky – Aaron Feb 04 '17 at 15:56
  • Just testing code which puts stuff in GCS. But, somehow its not working on devserver. It works if I upload it. – Teddy Feb 04 '17 at 17:54
  • Found this old SO question http://stackoverflow.com/questions/20158135/google-cloud-storage-on-appengine-dev-server . Could it just be that this limitation is still there today? – Teddy Feb 05 '17 at 02:19
  • I tried your second suggestion, and blobstore just works in devserver as well. – Teddy Feb 05 '17 at 03:11