Java Servlet登录筛选器排除列表不适用于整个文件夹

时间:2016-04-30 05:52:55

标签: java jsp tomcat servlets filter

我正在开发一个使用java和jsp的Web应用程序。要部署它,我正在使用tomcat 7.我正在使用LoginFilter将任何请求重定向到任何页面(除登录页面本身之外)到登录页面,除非用户输入了他们的用户名和密码

LoginFilter看起来像这样:

public class LoginFilter implements Filter {

    private List<String> urlList;

    @Override
    public void init(FilterConfig config) throws ServletException { 
        String skip = config.getInitParameter("avoid-urls");
        urlList = Arrays.asList(skip.split(","));
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
    throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String url = request.getServletPath();
        boolean allowed = false;

        boolean staticResources = (url.contains("css") || url.contains("images") || url.contains("js") || url.contains("login") || url.contains("reports");
        if(urlList.contains(url) || staticResources) {
            allowed = true;
        }
        if(!allowed) {
            HttpSession session = request.getSession(false);
            if(session == null || session.getAttribute("user") == null) {
                response.sendRedirect(request.getContextPath() + "login.jsp");
                return;
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() { }
}

在我的web.xml文件中,我将其映射为:

<web-app
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0"
    >

    <display-name>Test</display-name>

    <filter>
        <filter-name>Login Filter</filter-name>
        <filter-class>LoginFilter</filter-class>
        <init-param>
            <param-name>avoid-urls</param-name>
            <param-value>login.jsp, assets/*, reports/*, reports</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Login Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

现在,即使用户未登录,我希望他们能够输入:myurl/reports并返回报告文件夹(这只是一些文本文件)。目前,如果用户输入(没有正确的登录凭据),则会收到此错误:

HTTP Status 404 - /myurl/reports/
type  Status report
message  /myurl/reports/
description  The request resource is not available.

但是,如果他们实际在网址report1.txt中输入了报告名称(对于此示例,请将其称为myurl/reports/report1.txt),那么report1.txt将在没有登录凭据的情况下正常显示。

那么我应该怎么做才能允许整个文件夹没有登录凭证?

3 个答案:

答案 0 :(得分:2)

默认情况下,Tomcat servlet不显示目录内容。您找不到404,因为Tomcat正在查找不存在的文件index.jsp

要查看的其他问题:How can I list all the files in folder on tomcat?

要启用目录列表,您应该配置默认servlet以允许包含以下init-param的列表:

<init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
</init-param>

我不知道你在web.xml创建了一个servlet的位置,所以生病了一个可能的配置:

<web-app
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0"
    >

    <display-name>Test</display-name>

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.DefaultServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>Login Filter</filter-name>
        <filter-class>LoginFilter</filter-class>
        <init-param>
            <param-name>avoid-urls</param-name>
            <param-value>login.jsp, assets/*, reports/*, reports</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Login Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

答案 1 :(得分:0)

你应该使用

final HttpServletRequest request = (HttpServletRequest) req;
final String url = request.getRequestURI();

而不是

HttpServletRequest request = (HttpServletRequest) req;
String url = request.getServletPath();

编辑:我注意到你的Arrays.asList(skip.split(","))也会包含空格:

  

'login.jsp',..'reports'

因此urlList.contains(url)在这种情况下不起作用。

尽可能多地记录日志。记录每个请求。记录参数一个临时变量,你会发现错误。

答案 2 :(得分:0)

这些信息可能有助于重定向页面并允许某些页面取决于基于自己的权限

@WebFilter("/secured/*")
public class LoginFilter implements Filter {

    /**
     * Default constructor. 
     */
    public LoginFilter() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        // TODO Auto-generated method stub
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println(" loginFilter servlet begin ");
          HttpServletResponse httpResponse = (HttpServletResponse) response;
          HttpServletRequest httpRequest = (HttpServletRequest) request;
          String URI = ((HttpServletRequest)request).getRequestURI();
          HttpSession session =httpRequest.getSession(false);
          String emailFromWeb = null;
          String loginURL = httpRequest.getContextPath() + "/login.jsp";
          String rootURL = httpRequest.getContextPath() + "/secured/root.jsp";
          String userURL = httpRequest.getContextPath() + "/secured/user.jsp";
          String logoutURL=httpRequest.getContextPath() + "/logout";

          if(session==null){
              System.out.println("false inquery session is null");
              httpResponse.sendRedirect(loginURL);
              return;

          }
          emailFromWeb  = session.getAttribute("email").toString();     



              if  (httpRequest.getRequestURI().equals(loginURL)){
                  System.out.println("login page inquery");
                  chain.doFilter(request, response);
                  return;
              } 
              if(httpRequest.getRequestURI().matches(".*(css|jpg|png|gif|js)")){
                    System.out.println(" inquery by "+httpRequest.getRequestURI());
                    chain.doFilter(request, response);
                    return;
                }

//            if (httpRequest.getRequestURI().equals(rootURL)&&Authentication.isPermitted(emailFromWeb, "RootPage")) {
//                System.out.println("root page inquery");
//                chain.doFilter(request, response);
//                return;
//            } 

//            else if(httpRequest.getRequestURI().equals(userURL)&&Authentication.isPermitted(emailFromWeb, "UserPage")){
//                System.out.println("user page inquery");
//                chain.doFilter(request, response);
//                return;
//            }
              else if(httpRequest.getRequestURI().equals(logoutURL)){
                  System.out.println("logout inquery");
                  httpResponse.sendRedirect(loginURL);
                  return;
              }
              else {
                  System.out.println("false inquery");
                  httpResponse.sendRedirect(loginURL);
                  return;
              }



    }