google-app-engine


How to access a cloud storage bucket from app engine without getting the 403 FORBIDDEN error?


I would like to simply pull a list of the contents of my bucket from app engine and display them.
This works fine when I run it on the local dev server.
However, when I deploy the same code app engine, I get a 403 FORBIDDEN error.
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 FORBIDDEN
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Forbidden",
"reason" : "forbidden"
} ],
"message" : "Forbidden"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1056)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.alpine.servlets.TempServlet.getBucket(TempServlet.java:67)
at com.alpine.servlets.TempServlet.doGet(TempServlet.java:79)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:37)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:50)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:260)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:78)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:148)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:468)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:439)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:446)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:256)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:310)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:302)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:443)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:235)
at java.lang.Thread.run(Thread.java:745)
From my research I have determined that there are many potential causes for this error.
AccessDenied
AccountProblem
AnotherUserOwnsDomain
BucketAlreadyExists
CrossLocationLoggingProhibited
DomainVerificationRequired
InsufficientQuota
InvalidAccessKeyId
InvalidPayer
InvalidSecurity
RequestTimeTooSkewed
SignatureDoesNotMatch
However, I am not able to identify which of them applies to my situation from the stack trace.
The Google doc on this subject suggests that I should not have to do anything special to get this to work:
If you're running your application on Google App Engine or Google
Compute Engine, the environment already provides a service account's
authentication information, so no further setup is required. For
Compute Engine, the service account scope depends on how you created
the instance. See Setting the scope of service account access for
instances. For App Engine, the cloud-platform scope is used.
The app engine instance and the cloud storage buckets are in different projects, but I don't think that should be a problem because the scope is set to cloud-platform.
And the doc describe cloud-platform scope as:
View and manage data across all Google Cloud Platform services. For
Google Cloud Storage, this is the same as devstorage.full-control.
The code I am using to get a connection is borrowed directly from Google's java-doc-samples:
public class StorageFactory {
private static Storage instance = null;
public static synchronized Storage getService() throws IOException, GeneralSecurityException {
if (instance == null) {
instance = buildService();
}
return instance;
}
private static Storage buildService() throws IOException, GeneralSecurityException {
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = GoogleCredential.getApplicationDefault(transport, jsonFactory);
if (credential.createScopedRequired()) {
Collection<String> bigqueryScopes = StorageScopes.all();
credential = credential.createScoped(bigqueryScopes);
}
return new Storage.Builder(transport, jsonFactory, credential)
.setApplicationName("GCS Samples")
.build();
}
}
I am somewhat stumped as to how to debug this problem.
Use a library specifically built for App Engine. It's much easier to use.

Related Links

Login loop when adding a custom domain for appengine
InvalidClassException: No valid constructor
CookieJar does not catch incoming cookies
Google Cloud Console Projects, Advantage To Have Different Elements Under Same Project?
No api proxy found for service “datastore_v4” in new GAE 1.8.4
Which Google App Engine installer do I want to use for Windows?
Using Access Token from google cloud to login to Gmail
GAE : Yahoo, Google & Facebook login support
Google App Engine : JDO deletePersistent not consistent
Objectify 4 throwing strange error in GAE
How can I use my Google API email #developer.gserviceaccount.com
How to log messages in GAE go runtime?
Error with PHP SDK (Windows)
Increase Per-User Limit for Google API: Saving not possible, always error message “Your input was invalid”
GWT: form post works only on the local server, not with the app engine
NoClassDefFoundError: com/google/api/client/util/Lists when setting up oauth2 on app engine

Categories

HOME
localization
ecmascript-6
angular-formly
numbers
pclxl
seo
database-normalization
soa
aws-cli
vert.x
special-characters
sendgrid-api-v3
syntaxnet
owin
stellar.js
libusb
mapstruct
asciidoctor-pdf
imagemap
visual-studio-extensions
hta
easeljs
ckfinder
angularjs-components
nstimer
underscore.js
exchangewebservices
cppreference
finagle
glib
clickjacking
carriage-return
sql-server-ce
watchman
imagenet
sim-card
typesafe-config
p4merge
odoo-website
vmware-fusion
escpos
linqpad
microsoft-metro
smoothstate.js
builder
automapper-5
clarifai
convex-optimization
scalding
azure-cli
java-bytecode-asm
java-6
android-testing
reshape
rackspace-cloud
django-1.10
omxplayer
xcode-server
vulcanize
nservicebus5
sklearn-pandas
grass
jnlua
sapi
java-money
forwarding
rubaxa-sortable
eoferror
zscript
jsvc
keyup
osc
shopizer
public-html
nodelist
theos
angular-gettext
boost-program-options
punycode
ss7
twitter-bootstrap-rails
xmltodict
gd-graph
ie8-compatibility-mode
unit-of-work
nebula
font-awesome-4.0.0
subproject
fusefabric
clrstoredprocedure
dataform
objective-j
timertask
addchild
zend-rest
glui
tui
complex-event-processing
sifr3
scrubyt
change-management
online-storage

Resources

Encrypt Message