Alex Alex - 6 months ago 51
Java Question

Java Servlet Login Filter exclusion list not working on entire folder

I am working on a web application that uses java and jsp. To deploy it, I am using tomcat 7. I am currently using a

LoginFilter
that will redirect any request to any page (other then the login page itself) to the login page, unless the user has entered their username and password.

The
LoginFilter
looks like this:

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() { }
}


In my
web.xml
file I have it mapped like this:

<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>


Now, even if the user is not logged in, I want them to be able to type in:
myurl/reports
and get back the folder of reports (which are just some text files). Currently, if the user does type that in (without proper login credentials), they get this error:

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


But if they actually type in the report name (for this example lets call it
report1.txt
) at the URL:
myurl/reports/report1.txt
, then
report1.txt
will be displayed just fine without login credentials.

So what should I be doing so that I can allow an entire folder without login credentials?

ug_ ug_
Answer

By default Tomcat servlets do not show directory contents. You are getting a 404 not found because Tomcat is looking for the file index.jsp which doesnt exist.

Other SO question to look at: How can I list all the files in folder on tomcat?

To enable directory listings you should configure the default servlet to allow for listings with the following init-param:

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

I dont see where you created a servlet in your web.xml so ill create a possible configuration here for you:

<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>