我希望用户在访问 GAE (Google App Engine)应用程序的某些部分时使用登录/密码。我想限制对预定义用户集的访问,例如在页面上,可以将新数据上传到数据存储区。
我发现GAE有3种方法可以解决这个问题,但看起来只有最后一种(最复杂的)可以解决我的问题:
使用部署描述符(web.xml中的 <security-constraint>
)。这并不好,因为这些用户可以访问GAE应用程序的管理页面,他们可以查看帐单历史记录,浏览数据存储区,日志等,这是我必须要避免的。< / p>
使用联合登录(打开ID )(https://developers.google.com/appengine/articles/openid)并允许用户使用他们的Google,Yahoo!或其他登录身份。这不是一个解决方案,因为我想限制对一小组用户的访问(最多5个),并且不允许每个人都使用该应用程序。
另一个选项是创建只能通过HTTPS访问的简单自定义登录页,并让用户发送用户名&amp; POST请求中的密码(可以很简单,因为我们有安全的 https 连接)到servlet上,在servlet上生成一些具有指定有效性的会话标识符并使其成为每一个后续请求。如果会话标识符存在且同时未手动过期,则每次用户发送GET或POST请求时也需要进行检查。
有关如何维护管理员帐户的任何其他/更好的提案? HttpSession
可以帮助使用最后一个版本吗?
亲切的问候, 斯登
答案 0 :(得分:2)
我建议使用标准的Google登录页面。在您的身份验证控制器(Java + Jersey Framework,当然不是必需的)中使用类似的东西:
@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登录页面。注销方法将注销用户。
希望这有帮助
答案 1 :(得分:1)
我使用2和3的组合。我允许所有用户登录,但之后我将操作限制为特定的电子邮件地址。这些可以在数据存储区和内存缓存中进行硬编码或(更好)(这样您就不必在每个请求中查询数据存储区)。如果您愿意,也可以将这些数据缓存在Java中的静态变量中 - 只要知道如果您更改具有访问权限的用户,您可能需要手动终止实例。如果像我一样,你很少/永远不会改变访问权限,那么这应该不是问题。
允许所有用户登录确实无法访问我的应用程序 - 他们看到了管理页面,但除了显示“您无法访问任何这些管理选项”的消息外,它们都是空的。
答案 2 :(得分:1)
一些注意事项:
AFAIK您的假设不正确。登录应用程序与管理页面权限无关。您需要通过“权限”页面明确添加用户,以便他们可以访问管理页面。
用户使用OpenID登录后仍然可以检查用户属性(电子邮件),并拒绝他们访问。
这当然可行。跟踪用户的自然方式是sessions。谷歌的例子。
在两种情况下2.'3.建议使用servlet过滤器,如果用户已登录则检查会话,如果用户未登录则返回拒绝访问(返回404)。
答案 3 :(得分:-1)
注意第三个解决方案:而不是传递用户名&amp;密码我的webapp要求用户名&amp; 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;
}