如何保护servlet免受外部用户的侵害?

yas*_*een 1 java security google-app-engine

我试图在web.xml中使用security-constraint.我通过使用角色授予管理员权限.如何测试servlet是否安全并且只能由管理员访问?

jmo*_*253 8

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

如果由于某种原因测试失败,您需要确保已按照文档中的所有步骤来保护servlet并实现身份验证模式.以下概述了使用Google OAuth和UserService作为示例.

开箱即用,Google App Engine为您提供了在应用程序中使用的两个角色:用户和管理员.

管理员用户被定义为在Google App Engine项目中列为三个角色中的任何一个的任何用户,因此,如果您想授予某人管理员访问您的servlet的权限,您可以在http://中将其添加为查看者appengine.google.com面板.

UserService类,您可以访问登录的用户.您需要使用此功能为您的用户创建登录网址,使用他或她的Google帐户通过Google登录,将他或她重定向到您的应用程序,然后UserService.isUserAdmin()用来确定该用户是否确实是管理员用户.

使用用户服务详细描述了如何开始使用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()));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

谷歌应用程序引擎用户的Java API概述了如何在谷歌应用程序引擎的用户处理日志记录:

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>");
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

保护Servlet:

如果您有用户除非已登录就无法访问的页面,您可以为部署描述符中的那些页面建立安全约束(web.xml

" 部署描述符:安全性和身份验证"页面演示了如何修改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>
Run Code Online (Sandbox Code Playgroud)

在此示例中,/profile具有任何角色的用户可以访问servlet *,并且/admin只有具有该角色的用户才能访问servlet admin.

虽然Google App Engine Java确实具有内置安全性,但角色有限.如果您需要更精细地控制用户的角色,请参阅Luke Taylor在Google App Engine中的Spring Security上的帖子.该示例很旧,但如果您将日志记录级别提升到TRACE,则可以使其在最新版本的Spring和最新的GAE SDK上运行.