如何防止通过浏览器直接调用servlet

Posted

技术标签:

【中文标题】如何防止通过浏览器直接调用servlet【英文标题】:how to prevent servlet from being invoked directly through browser 【发布时间】:2013-12-20 10:53:32 【问题描述】:

我正在开发一个使用 java servlet 和 jsp 页面的 Web 项目。在其中一个 servlet 中,我们有 RequestDispatcher 方法,它正在调用另一个 servlet。

@WebServlet("/Demo")
public class DemoServlet extends HttpServlet   

    public void doGet(HttpServletRequest req, HttpServletResponse res)  
            throws ServletException, IOException   
        res.sendRedirect("testing"); //calling other servlet 
      
  

@WebServlet("/测试") 公共类 TestingServlet 扩展 HttpServlet 公共无效doGet(HttpServletRequest请求,HttpServletResponse res) 抛出 ServletException,IOException response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("Hello World");

所以,现在我想阻止从浏览器直接调用 contextRoot/testing,而是只让它从另一个 servlet(Demo) 调用

如果有什么办法,请给我建议。

【问题讨论】:

如果您不希望通过浏览器访问第二个 servlet,为什么不直接在第一个 servlet 中实现它的功能? 【参考方案1】:

存在几种技术:

看看编写一个 HTTP 请求过滤器。然后,您可以检查传入的请求和 url,如果模式与您不想直接调用的 servlet 路径匹配,则拒绝它。

另一种机制是使用 web.xml 中的安全约束来允许仅授权用户/角色访问应用程序中的各种路径。查看web.xml中的<security-constraint>标签

【讨论】:

【参考方案2】:

一种方法是使用ServletRequest.getRemoteAddr()检查调用者的ip,如果没有在本地调用则拒绝它

public void doGet(HttpServletRequest req, HttpServletResponse res)  
            throws ServletException, IOException   
  if(!req.getRemoteAddr().equals("127.0.0.1"))  // reject 

但是这种方法不起作用合法调用者(例如:代理)也使用相同的 ip。

【讨论】:

【参考方案3】:

“罗明”给出的答案是正确的。您必须为此使用过滤器。您可以做的是,您可以在访问“/Demo” url 时设置一个新的会话变量,并在过滤器中检查会话存在的条件,如果存在则允许该 url,否则抛出错误。你可以做类似的事情。在“Demo”servlet中

@WebServlet("/Demo")
public class DemoServlet extends HttpServlet   

    public void doGet(HttpServletRequest req, HttpServletResponse res)  
            throws ServletException, IOException   
        HttpSession session = request.getSession() //get new session
        res.sendRedirect("testing"); //calling other servlet 
      
  

在过滤器类中添加以下代码

 @WebFilter("/login")
 public class MyFilter implements Filter  

    public void init(FilterConfig arg0) throws ServletException   

    public void doFilter(ServletRequest req, ServletResponse resp,  
        FilterChain chain) throws IOException, ServletException   

        HttpRequest request = (HttpRequest) req;
        HttpResponse respone = (HttpResponse) res;

        HttpSession session = request.getSession(false) //get the existing session object
        if(null != session) 
         chain.doFilter(req, resp);
         else 
           "redirect to some error page or home page"
          
    
        public void destroy()   
  

【讨论】:

以上是关于如何防止通过浏览器直接调用servlet的主要内容,如果未能解决你的问题,请参考以下文章

微信发一个网址打开后自动调用手机自带默认浏览器或提示选择浏览器打开如何实现?

如何在 Web 浏览器中启用 Java

如何在调用 servlet 后使用 ajax 在 iframe 中显示 PDF

用户在Laravel中更新密码后自动退出。我怎么防止这个?

防止使用浏览器 url 直接访问图像

java web 如何防止 用户绕过js验证,直接地址栏提交表单或自己编写html页面,提交数据到服务器?