2012-04-10 72 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