【问题标题】:Authentication on Google App Engine (web page)Google App Engine 上的身份验证(网页)
【发布时间】:2014-01-24 17:32:54
【问题描述】:

我想要求用户在访问我的 GAE (Google App Engine) 应用程序的某些部分时使用登录名/密码。我想限制对一组预定义用户的访问,例如在页面上,可以将新数据上传到数据存储区。

我发现 GAE 有 3 种方法可以解决这个问题,但看起来只有最后一种(最复杂的)可以解决我的问题:

  1. 使用部署描述符(<security-constraint> in web.xml)。这不好,因为这些用户可以访问,即使作为 GAE 应用程序管理页面的查看者,他们可以在其中查看账单历史记录、浏览数据存储、日志等,这是我必须避免的。

  2. 使用联合登录 (Open ID) (https://developers.google.com/appengine/articles/openid) 并允许用户使用他们的 Google、Yahoo!或其他身份登录。这不是一个解决方案,因为我想限制一小部分用户(最多 5 个)的访问权限,并且不允许每个人都使用该应用程序。

  3. 另一种选择是创建仅可通过 HTTPS 访问的简单 自定义登录页面,并让用户在 POST 请求中发送用户名和密码(它可以很简单,因为我们有安全 https 连接)到 servlet,在 servlet 上生成一些具有指定有效性的 会话标识符 并使其成为每个后续请求的一部分。它还需要在用户每次发送 GET 或 POST 请求时手动检查会话标识符是否存在且未同时过期。

关于如何维护管理员帐户的任何其他/更好的建议? HttpSession 可以帮忙解决最后一个变种吗?

亲切的问候, 钢

【问题讨论】:

  • 您在这里将两个完全独立的问题混为一谈,身份验证和授权。您可以将前两个解决方案(身份验证)中的任何一个与您自己的解决方案结合起来检查授权。执行此操作的最简单方法是在数据存储中维护允许用户的列表,并在用户登录时查找用户以检查权限,如下面的 Peter 和 Adam 建议的那样。

标签: google-app-engine authentication servlets httpsession google-openid


【解决方案1】:

我建议使用标准的 Google 登录页面。在您的身份验证控制器中使用类似的东西(Java + Jersey 框架,这当然不是必需的):

@Path("/login")
public Response login(@Context UriInfo ui) throws Exception {
  UserService userService = UserServiceFactory.getUserService();
  com.google.appengine.api.users.User user = userService.getCurrentUser();
  Response response;
  if (user == null) {
    URI uri = new URI(userService.createLoginURL(ui.getBaseUri().toString()));
    response = Response.seeOther(uri).build();
  } else {
    URI uri = new URI("/");
    response = Response.seeOther(uri).build();
  }
  return response;
}

@GET
@Path("/logout")
public Response logout(@Context UriInfo ui) throws Exception {
  UserService userService = UserServiceFactory.getUserService();
  com.google.appengine.api.users.User user = userService.getCurrentUser();
  Response response;
  if (user == null) {
    URI uri = new URI("/");
    response = Response.seeOther(uri).build();
  } else {
    URI uri = new URI(userService.createLogoutURL(ui.getBaseUri().toString()));
    response = Response.seeOther(uri).build();
  }
  return response;
}

如果用户未登录(基本上未登录),登录方法会将您的应用重定向到 Google 登录页面。 logout 方法会注销用户。

希望对你有帮助

【讨论】:

    【解决方案2】:

    我使用 2 和 3 的组合。我允许所有用户登录,但我将操作限制在特定的电子邮件地址。这些可以硬编码或(更好)在数据存储和内存缓存中(这样您就不必在每个请求上查询数据存储)。如果您愿意,您还可以将此数据缓存在 Java 中的静态变量中 - 请注意,如果您更改有权访问的用户,您可能需要手动终止实例。如果像我一样,您很少/从不更改访问权限,那么这应该不是问题。

    允许所有用户登录实际上使他们无法访问我的应用程序 - 他们看到管理页面但除了一条消息说“您无权访问这些管理选项中的任何一个”之外它们是空的。

    【讨论】:

    • 任何人都可以在 Servlet 端分享一些示例代码吗?
    【解决方案3】:

    一些注意事项:

    1. AFAIK 你的假设不正确。登录到应用程序与管理页面权限无关。您需要通过“权限”页面明确添加用户,以便他们访问管理页面。

    2. 在用户使用 OpenID 登录后,您仍然可以检查用户属性(电子邮件)并拒绝他们访问。

    3. 这当然是可行的。跟踪用户的自然方式是sessions。谷歌示例。

    在这两种情况下 2.' 3. 建议有一个 servlet 过滤器,如果有用户登录则检查会话,如果用户未登录则拒绝访问(返回 404)。

    【讨论】:

      【解决方案4】:

      注意第三种解决方案:我的 web 应用程序不传递用户名和密码,而是询问用户名和 apiSecret(在第一次登录时自动生成),因此如果出现问题,您可以快速使 apiSecret 无效(并重新生成)。

      还有另一个选项:OAuth (https://developers.google.com/appengine/docs/java/oauth/)。 这是我的一段代码(UserAccount 是我的代表用户的类;用户是“com.google.appengine.api.users.User”,retrieveUser(..) 是从登录的“用户”中检索我的 UserAccount 的函数):

      public UserAccount getUserLogged(HttpServletRequest request) {
          try {
              User loggedUser = oauthService.getCurrentUser();
              if(loggedUser!=null) {
                  return super.userAB.retrieveUser(loggedUser);
              }
          } catch (OAuthRequestException e) {
              return null;
          }
          return null;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多