【发布时间】:2012-04-10 14:15:45
【问题描述】:
我尝试在 web.xml 中使用安全约束。我使用角色授予管理员权限。如何测试servlet是否安全,是否只能由管理员访问?
【问题讨论】:
标签: java security google-app-engine
我尝试在 web.xml 中使用安全约束。我使用角色授予管理员权限。如何测试servlet是否安全,是否只能由管理员访问?
【问题讨论】:
标签: java security google-app-engine
要测试 servlet,您至少需要两个 Google 帐户。在您的 Google App Engine 管理控制台上,必须至少将一个 Google 帐户添加为查看者,而不得添加另一个 Google 帐户。未在管理控制台中添加的 Google 帐户应该无法访问角色定义为 admin 的任何 servlet。
如果由于某种原因测试失败,您需要确保您已按照文档中的所有步骤来保护 servlet 并实施身份验证架构。下面以 Google OAuth 和 UserService 为例进行概述。
开箱即用,Google App Engine 为您提供了两个可在应用程序中使用的角色:用户和管理员。
管理员用户定义为在 Google App Engine 项目中列为 any one of the three roles 的任何用户,因此如果您想授予某人管理员访问您的 servlet 的权限,您可以在 http://appengine.google.com 面板中将他们添加为查看者.
UserService 类使您可以访问已登录的用户。您需要使用它为您的用户创建登录 URL,使用他或她的 Google 帐户通过 Google 登录,将他或她重定向到您的应用程序,然后使用 UserService.isUserAdmin() 确定该用户是否确实是管理员用户。
Using the Users Service 详细描述了如何开始使用 UserService 类。
package guestbook;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
public class GuestbookServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user != null) {
resp.setContentType("text/plain");
if(userService.isUserAdmin()) {
resp.getWriter().println("Hello, " + user.getNickname() + ", you are logged in as an admin");
} else {
resp.getWriter().println("Hello, " + user.getNickname());
}
} else {
resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
}
}
}
Google App Engine Users Java API Overview 演示了如何在 Google App Engine 上处理登录用户:
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
UserService userService = UserServiceFactory.getUserService();
String thisURL = req.getRequestURI();
resp.setContentType("text/html");
if (req.getUserPrincipal() != null) {
resp.getWriter().println("<p>Hello, " +
req.getUserPrincipal().getName() +
"! You can <a href=\"" +
userService.createLogoutURL(thisURL) +
"\">sign out</a>.</p>");
} else {
resp.getWriter().println("<p>Please <a href=\"" +
userService.createLoginURL(thisURL) +
"\">sign in</a>.</p>");
}
}
}
保护 Servlet:
如果您的页面只有登录后用户才能访问,您可以在部署描述符(web.xml)中为这些页面建立安全约束
Deployment Descriptor: Security and Authentication 页面演示了如何修改您的 web.xml,以便只有管理员可以访问某些 servlet。
<security-constraint>
<web-resource-collection>
<url-pattern>/profile/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
在本例中,* 表示的任何角色的用户都可以访问 servlet /profile,而/admin servlet 只能由角色admin 的用户访问。
虽然 Google App Engine Java 确实具有内置的安全性,但角色有些受限。如果您需要对用户角色进行更精细的控制,请参阅Luke Taylor's Post on Spring Security in Google App Engine。该示例很旧,但如果您将日志记录级别提高到 TRACE,则可以使其在最新版本的 Spring 和最新的 GAE SDK 上运行。
【讨论】: