【问题标题】:How to protect a servlet from external users?如何保护 servlet 免受外部用户的攻击?
【发布时间】:2012-04-10 14:15:45
【问题描述】:

我尝试在 web.xml 中使用安全约束。我使用角色授予管理员权限。如何测试servlet是否安全,是否只能由管理员访问?

【问题讨论】:

    标签: java security google-app-engine


    【解决方案1】:

    要测试 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 上运行。

    【讨论】:

    • 我认为如果没有 Spring Framework 的其余部分,我们就无法使用 Spring Security。有没有类似的东西我们可以使用而不被强制使用特定的框架?谢谢
    • @husayt - Spring 是相当模块化的。 Spring Security 包含一个 applicationSecurity-Context.xml,我在其中定义了哪些 URL 模式映射到了哪些角色,剩下的就是历史记录。我能够锁定静态文件,因此您可以将其应用于不属于框架的内容。简而言之,您必须尝试一下才能确定。
    猜你喜欢
    • 1970-01-01
    • 2011-10-02
    • 2020-05-12
    • 2016-10-28
    • 2016-03-13
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多