GAE HttpResponseException:401

时间:2017-05-22 06:38:21

标签: java google-app-engine authentication google-cloud-datastore remoteapi

我正在尝试使用Remote API从另一个GAE项目访问一个应用程序的DataStore。 我使用以下代码:

        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;
    }

当我在本地运行时,我在installer.install(options);得到一个nullpointerexception。 部署时,从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!")));

这一个有效!!添加了Hello Remote API实体。

1 个答案:

答案 0 :(得分:0)

在App Engine上运行与在本地运行时不起作用的原因与正在拾取的凭据有关。在本地运行时,它可能使用您自己的凭据(可以访问这两个项目);相比之下,在App Engine上运行时,您可能会选择App Engine默认服务帐户,该帐户只能访问该App Engine项目。

尝试通过打开包含您要访问的Cloud Datastore的项目的Cloud IAM section of Cloud Console来解决此问题。在那里,授予对其他项目正在使用的默认App Engine服务帐户的适当访问级别。

如果您不希望其他项目中的所有App Engine服务都具有此类访问权限,您可能还会考虑为此跨项目访问生成service account,并授予其相应的访问权限to(而不是授予对默认App Engine服务帐户的访问权限)。然后,在调用API的代码中,您将通过调用RemoteApiOptions的{​​{3}}方法明确使用该服务帐户,以确保发出的API请求使用指定的服务帐户而不是默认值App Engine服务帐户。