【问题标题】:How to disable direct access to jsp pages?如何禁用对jsp页面的直接访问?
【发布时间】:2014-12-18 13:47:31
【问题描述】:

我在 java 项目中有一个 jsp 页面,我使用下面的代码从 url 隐藏 jsp 扩展名,但也在 url 中加载带有 jsp 扩展名的页面。如何防止这种情况? 我的代码:

<servlet> 
<servlet-name>myTest</servlet-name>
<jsp-file>/testing.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>myTest</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>

并且url测试是:localhost/testing.jsp,我的测试页面是访问。

【问题讨论】:

    标签: java jsp servlets


    【解决方案1】:

    为了快速解决,只需将您的 JSP 页面放到 WEB-INF 文件夹中(这样它们将无法直接访问)并像这样定义它们:

       <servlet>
            <description>
            </description>
            <display-name>hidden</display-name>
            <servlet-name>hidden</servlet-name>
            <jsp-file>/WEB-INF/hidden.jsp</jsp-file>
        </servlet>
        <servlet-mapping>
            <servlet-name>hidden</servlet-name>
            <url-pattern>/hidden</url-pattern>
        </servlet-mapping>
    

    但您应该考虑使用框架来执行此操作,例如 Struts2 或 Spring。

    【讨论】:

    • @Digicom 对于我提供的解决方案,您不需要任何框架。框架只是供未来考虑的建议。
    • 我已经看到多个答案暗示了这一点,但它对我来说根本不起作用。在 URL 中包含“WEB-INF”仍然允许直接访问 JSP。
    • @Reinderien 您使用的是什么服务器/网络容器?大多数服务器默认保护 WEB-INF,所以我对你所描述的行为感到非常惊讶。
    • @Gas Jetty 9。对我来说很奇怪。我最终为 web.xml 添加了一个安全限制,这成功了。
    • @Reinderien 看起来像 Jetty 中的错误,该目录不应该按规范公开,因此您应该在 Jetty 论坛中报告该问题。来自 Jetty 文档:/WEB-INF/- Special Servlet API defined directory used to store anything related to the Web Application that are not part of the public access of the Web Application. If there is content that is accessed by a Web Application internally, but that should also never be accessed directly by a web browser, this is the directory it would placed in.
    【解决方案2】:

    您也可以使用过滤器并拒绝对 jsps 的访问。

    <filter>
       <filter-name>JspFilter</filter-name>
       <filter-class>my.JspFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>JspFilter</filter-name>
      <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    

    过滤器:

    public class JspFilter implements Filter{
      public void  doFilter(ServletRequest request, ServletReponse response,                
               FilterChain chain) {
        HttpServletRequest req= (HttpServletRequest) request;
        req.getRequestDispather("error.jsp).forward(request,response);
      }
    }
    

    【讨论】:

    • 从测试来看,这会导致一个无限循环错误,因为 dispatch error.jsp 会被过滤器捕获。
    【解决方案3】:

    我会将 url 映射到 servlet,然后从 servlet 返回 jsp。例如:

    在网页 xml 中:

    <servlet>
        <servlet-name>testServlet</servlet-name>
        <servlet-class>com.yourpackage.testServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
    

    在 servlet 中:

    request.getRequestDispatcher("testing.jsp").forward(request, response);
    

    因此,您的 url 模式将是 /test,但会加载 testing.jsp 页面。希望这会有所帮助。

    【讨论】:

    • 谢谢,但是这样每个jsp页面都会是一个servlet,对吧?没有别的办法吗?
    • 是的,它可能会。但是可能你可以将多个 URL 映射到同一个 servlet,然后使用他的请求 url 来确定要返回哪个 jsp。我个人使用 Spring MVC 框架来做你想做的事情,它变得容易多了。
    【解决方案4】:

    您可以通过将以下内容添加到您的 web.xml 中来阻止对 jsp 文件的直接访问,并根据需要更改 url 模式。

    <security-constraint>
            <web-resource-collection>
                <web-resource-name>JSP Files</web-resource-name>
                <description>No direct access to JSP files</description>
                <url-pattern>/pages/*</url-pattern>
                <http-method>POST</http-method>
                <http-method>GET</http-method>
            </web-resource-collection>
            <auth-constraint>
                <description>No direct browser access to JSP files</description>
                <role-name>NobodyHasThisRole</role-name>
            </auth-constraint>
        </security-constraint> 
    

    【讨论】:

    • 这会限制所有请求,即使我无法访问 /pages/login.jps 之类的登录页面
    猜你喜欢
    • 2016-02-03
    • 1970-01-01
    • 2011-11-09
    • 2020-08-17
    • 1970-01-01
    • 2017-11-22
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多