GAE HttpResponseException: 401
Я пытаюсь получить доступ к хранилищу данных одного приложения из другого проекта GAE с помощью удаленного API. Я использую следующий код:
String serverString = "http://example.com";//this should be the target appengine
RemoteApiOptions options;
if (serverString.equals("localhost")) {
options = new RemoteApiOptions().server(serverString, 8080).useDevelopmentServerCredential();
} else {
options = new RemoteApiOptions().server(serverString, 80).useApplicationDefaultCredential();
}
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
datastore = DatastoreServiceFactory.getDatastoreService();
try {
results = datastore.get(KeyFactory.createKey("some key"));
} catch (EntityNotFoundException e) {
e.printStackTrace();
return null;
}
когда я запускаю это локально, я получаю nullpointerexception в installer.install(options);
, и при развертывании ошибка, замеченная в сообщениях об ошибках в appengine:HttpResponseException: 401 You must be logged in as an administrator, or access from an approved application.
При этом я сделал небольшое Java-приложение со следующим кодом:
String serverString = "http://example.com";//same string as the one used in the above code
RemoteApiOptions options;
if (serverString.equals("localhost")) {
options = new RemoteApiOptions().server(serverString, 8080).useDevelopmentServerCredential();
} else {
options = new RemoteApiOptions().server(serverString, 80).useApplicationDefaultCredential();
}
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
try {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
System.out.println("Key of new entity is " + ds.put(new Entity("Hello Remote API!")));
и этот работает!! Здравствуйте, удаленный объект API добавлен.
1 ответ
Причина, по которой он не работает при запуске на App Engine против локального, связана с полученными учетными данными. При локальном запуске он, вероятно, использует ваши собственные учетные данные (которые имеют доступ к обоим проектам); напротив, при работе в App Engine вы, вероятно, выбираете учетную запись службы App Engine по умолчанию, которая имеет доступ только к этому проекту App Engine.
Попробуйте исправить это, открыв раздел Cloud IAM Cloud Console для проекта, содержащего Cloud Datastore, к которому вы хотите получить доступ. Там предоставьте соответствующий уровень доступа к учетной записи службы App Engine по умолчанию, которая используется другим проектом.
Если вы не хотите, чтобы все службы App Engine в другом проекте имели такой вид доступа, вы можете вместо этого создать учетную запись службы для этого межпроектного доступа, которому вы предоставляете соответствующий доступ (вместо того, чтобы предоставлять этот доступ). доступ к учетной записи службы App Engine по умолчанию). Затем в своем коде, который вызывает API, вы бы явно использовали эту учетную запись службы, вызвав метод useServiceAccountCredential() RemoteApiOptions
чтобы убедиться, что отправляемые запросы API используют указанную учетную запись службы, а не учетную запись службы App Engine по умолчанию.