【问题标题】:How to secure a Google cloud endpoint method which is called as a task?如何保护被称为任务的谷歌云端点方法?
【发布时间】:2015-04-08 22:41:45
【问题描述】:

我有一个 Android 应用程序与我的 Google 云端点后端通信。

在其中一个端点方法中,我将一个“任务”推送到队列中。

任务由另一个端点方法处理,例如"/taskendpoint/doSomeWork"

我已按照此处的建议将“/_ah/spi/taskendpoint/*”的访问权限限制为“管理员用户”,从而保护了此端点方法(处理任务功能) - https://developers.google.com/appengine/docs/java/taskqueue/overview-push#Java_Securing_URLs_for_tasks

我已经从浏览器中检查过,一切都按预期工作,只允许管理员用户访问该 url。

但是,现在的另一个问题是,相同的任务端点和方法在浏览器的 Google 端点 API 资源管理器中可见,任何人都可以在此处输入值并使用任务方法。我如何使这个方法在 API 资源管理器中不可见,因为只有任务需要这个方法?

另外,虽然我的应用程序使用 OAuth 身份验证,但它是用于身份验证 android 客户端,在这种情况下,它只是一个端点方法通过任务调用另一个端点方法。

我找不到很多关于这方面的文档,所以我很感激任何帮助

【问题讨论】:

  • 一种解决方法可能是我可以知道 API Explorer 是否调用了端点方法,然后在代码中拒绝该请求。有没有办法知道 API Explorer 是否调用了端点方法?
  • 是的,这就是解决方案。在您的端点类中,您应该在顶部的@Api 部分中有一行看起来像clientIds = {com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID, your_android_client_id}。移除 api explorer 项。
  • 这些字段没有在任务的 oauth 结构中使用,因为对任务方法的调用是从应用程序引擎内部进行的,而不是 android 客户端,没有使用 auth。如果使用了 auth ,这将使得有必要对任务请求进行身份验证,并且没有干净的方法可以做到这一点。在下面找到了一种更简单的方法来解决这个问题..

标签: android google-app-engine oauth-2.0 google-cloud-endpoints


【解决方案1】:

这就是我最终解决阻止任何外部请求访问我的任务 URL 的整体问题的方法 -

首先,使用https://developers.google.com/appengine/docs/java/taskqueue/overview-push#Java_Securing_URLs_for_tasks阻止“_ah/spi”访问任务url(原帖中已经提到)

其次,现在阻止访问“_ah/api”(这是主要问题)对通过 API 资源管理器进入的任务 url 的请求,这就是我所做的 -

将 HttpServletRquest 添加到端点方法并检查任何与任务相关的标头,例如"X-AppEngine-QueueName"

根据文档,GAE 确保只有来自任务的请求包含这些标头,其他请求不会包含这些标头。

因此,当您从 API 资源管理器调用方法时,这些标头为空,您可以为收到的此类请求引发异常,这些请求不是来自任务。下面给出一个简短的代码示例 -

@ApiMethod(name = "sendMessage", httpMethod = HttpMethod.POST)
public void sendMessage(HttpServletRequest req, @Named("messageText") String MessageText)
{
    String str = req.getHeader("X-AppEngine-QueueName");
    if(str==null)
    {
        // throw invalid request exception here 
    }

...

【讨论】:

    【解决方案2】:

    1) 向方法添加用户参数以进行身份​​验证

    @ApiMethod(name = "test", path = "myApi/test",
              scopes = {Constants.EMAIL_SCOPE},
                clientIds = {Constants.WEB_CLIENT_ID, 
                         Constants.ANDROID_CLIENT_ID, 
                         com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID},
                         audiences = {Constants.ANDROID_AUDIENCE})
      public User test(User user) throws UnauthorizedException    {
    
          if (user == null) throw new UnauthorizedException("User not valid!");   
    
          return user;
      }
    

    2) 生成令牌

    https://developers.google.com/accounts/docs/OAuth2WebServer

    3) 使用之前创建的令牌

    GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);

    https://code.google.com/p/google-api-java-client/wiki/OAuth2

    【讨论】:

      猜你喜欢
      • 2015-01-27
      • 1970-01-01
      • 2023-04-01
      • 2015-10-27
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多