2012-04-10 54 views

回答

9

要测试servlet,您至少需要两个Google帐户。必须在Google App Engine管理控制台中至少添加一个Google帐户作为查看器,而不能添加其他Google帐户。未在管理控制台中添加的Google帐户不应该能够访问角色被定义为admin的任何servlet。

如果由于某种原因测试失败,您需要确保您已遵循文档中的所有步骤来保护servlet并实现身份验证模式。下面以Google OAuth和UserService为例进行概述。

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演示了如何在谷歌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。

+0

我不认为如果没有Spring框架的其余部分,我们可以使用Spring Security。有没有类似的东西我们可以使用,而不必被强制在特定的框架上?谢谢 – husayt 2012-04-10 11:22:16

+1

@husayt - Spring相当模块化。 Spring Security由applicationSecurity-Context组成。xml在哪里我定义了哪些URL模式映射到哪些角色,其余的是历史。我能够锁定静态文件,因此您可以将它应用于不属于框架一部分的内容。总之,你必须尝试一下才能真正找到答案。 – jmort253 2012-04-11 07:47:35

+0

优秀的答案! – nhaarman 2013-08-15 21:55:15