I use Jersey for my REST API. I use JSP files for the views. I put my JSP view files in www/views/.... Now I'd like to forbid access to these views through simple HTTP request on their canonical URL.
What is the best way to forbid direct access to these JSPs from the client ?
Stick the JSPs under /WEB-INF in the WAR.
As johna has already said, if you put the .jsp files under WEB-INF this will prevent any access to them from the web directly.
If you want finer-grained security controls I would investigate a tool like Spring Security which will let you set up more complex security rules.
Related
I'd like to know if anyone has a solution to access resources of a website through a servlet only.
I have all my resources under WEB-INF. In other words, I don't want users to have direct access to any of my resources.
You can use ServletContext#getResource() for that.
URL resource = getServletContext().getResource("/WEB-INF/file.ext");
File file = new File(resource.getPath());
// ...
You can even use ServletContext#getResourceAsStream() to get an InputStream directly:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/file.ext");
// ...
As you can see in the examples, the ServletContext is available in servlets by the inherited GenericServlet#getServletContext() method.
That said, the phrase I don't want users to have direct access to any of my resources. is a bit contradicting. You're serving those resources by a servlet anyway? A servlet is directly accessible by URL. How is that different from "direct access"? Or do you just want to control the access based on some conditions? I'd say, a Filter is more suitable for this task.
Usually one would only fully hide the JSP files from direct access. In a Servlet which acts as front controller (according the MVC pattern) you could then forward requests to JSP files using RequestDispatcher#forward() which you in turn can obtain by ServletRequest#getRequestDispatcher().
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
You can hide jsp from the end user. In fact, you don't even have to deploy original jsp files with your web application, you can precompile them:
http://tomcat.apache.org/tomcat-5.5-doc/jasper-howto.html#Web%20Application%20Compilation
And the only way to hide html/js/css files is not to use them. Anything that's sent to the browser can be viewed there.
I have a simple web app that allows the user to upload and access files. When the user accesses an uploaded file, the server needs to support all of the header types such as Accept-Ranges so that partial-content responses can be made on large media files. The DefaultServlet (in Tomcat) handles everything well in its serveResource() method called by doGet(), so I would like to use the DefaultServlet for the uploaded files. This is easy enough in normal circumstances since it is the DEFAULT servlet, but unfortunately for my case, I am unable to find a way to use the default servlet.
In order to prevent the uploaded files from being deleted when the webapp is redeployed, I need to store them outside of the webapp directory.
These files should only be accessible to the user that uploaded them, so I created a javax.servlet.Filter to handle resource access authorization. I know that if I add a new context in server.xml for the external resource directory, they will be accessible, and the DefaultServlet will be used.
<Context docBase="/path/to/resources" path="/resource" />
But I do not want to do that because then I am required to invasively modify server.xml which is not recommended (for reasons), and when a context exists for the /resource path, my filter for that url-mapping will not be invoked. So I do not think creating a new context is a good solution.
The only other solution I can think of would be to create a servlet for all requests at '/resource/*' which extends DefaultServlet, and somehow override functionality that would instead get the requested file at its actual external location rather than returning 404 on the non-existent resource in the webapp.
However, I have not been able to find an easy way to convert the DefaultServlet into one that can fetch files external to the webapp directory. Maybe there is a way?
How would I go about handling this?
Not an answer
In order to prevent the uploaded files from being deleted when the
webapp is redeployed
It means you are re-deploying your stuffs wrong(in a very bad manner), probably using war files, or worse(worst) tomcat manager.
I know that if I add a new context in server.xml for the external
resource directory, they will be accessible, and the DefaultServlet
will be used.
You are right, but you are wrong about having another context, it's not necessary.
Solutions:
Dear Michael-O specified the easiest and probably best answer.
You may also implement something like DefaultServlet too, sometimes(not for your case) it's better to implement things from zer0 rather than configuring and maintaining many too much complex stuffs.
I'm working on a small web application that contains some JSPs, Servlets and static HTML pages. There are also some filters to implement a small authentication/authorization mechanism. My questions are:
How can I map an entire directory of JSPs to another? Here's an example: I want to map all the URLs like localhost:8080/WebAppName/pages/*.jsp to localhost:8080/WebAppName/*.jsp . How can I do that without writing an entry in the web.xml for each JSPs page in the directory 'pages'?
After having mapped these URLs to new ones, what do I have to write in the tag of in the web.xml? The mapped URL (WebAppName/*.jsp) or the real one (WebAppName/pages/*.jsp)?
Thanks in advance.
You could make a servlet - or JSP - that has a mapping *.xhtml (other extension). Using the request URI it can do a dynamic include of the corresponding JSP from pages.
In servlet:
String pagesPath = "pages/" + ...;
request.getServletContext(pagesPath).getRequestDispatcher().include(request,
response);
I doubt it is a good idea, as it does not add something: you might even need to adapt all JSPs (other extension). Or rename the JSPs to .jspf.
In general I use JSPs under WEB-INF/jsp or so; so they are not publicly accessible. And use a similar technique: creating a model in the servlet, and then to the view as JSP.
We want to share user validation configuration between a Java validation class (for sanity checking) and a Javascript-enabled form web interface (for usability). What's the best way to deploy this static file in our web application so that it is both available to the server-side code, and available via a URL accessed by the client?
So far I've thought of putting the file in the application root and pointing the validation class at it when it is used, and putting the file in the WEB-INF/classes directory and somehow configuring the container to serve it.
Has anyone else configured a web application like this? What did you end up doing?
Yeah. Put it in the WEB-INF/classes and have a servlet serve out the relevant portion of the validation configurations based on something like a form-id. Better yet, have the servlet transform the configuration into a JSON object and then you can simply include a script tag and start using it :)
I have a very basic question about MVC web applications in Java.
Since the olden days of raw JSP up until current technologies like Seam, a very basic pattern has always been the internal dispatch from the controller that initially accepted the request to the view layer that creates the output to be sent to the client.
This internal dispatch is generally done (although the mechanism may be hidden through an extra layer of configuration) by asking the servlet container for a new resource using a URL. The mapping of these URL are done by the same web.xml that also defines the "real" URL to the outside.
Unless special measures are taken, it is often possible to directly access the view layer directly. Witness the Seam "registration" demo, where you can bypass "register.seam" and directly go to "registered.xhtml". This is a potential security problem. At the very least, it leaks view template source code.
I am aware that this is only a basic sample application, but it is also strange that any extra measures should need to be taken to declare these internal resources invisible to the outside.
What is the easiest way to restrict URL entry points?
Is there maybe something like the "WEB-INF" directory, a magic URL path component that can only be accessed by internal requests?
You can prevent access to internal resources by using a security-constraint in your web.xml deployment descriptor.
For example, I use the following configuration to prevent direct access to JSPs:
<!-- Prevent direct access to JSPs. -->
<security-constraint>
<web-resource-collection>
<web-resource-name>JSP templates</web-resource-name>
<url-pattern>*.jsp</url-pattern>
</web-resource-collection>
<auth-constraint/> <!-- i.e. nobody -->
</security-constraint>
I would not recommend allowing Internet requests to directly access your appserver. I'd throw a webserver in front, then in it, allow the request of certain kinds of URLs. Don't want people to go to foo.com/jsps? Restrict it once and for all there.
There's a bit of a conversation on the topic here: hiding pages behind WEB-INF?
One way to handle this would be to construct a Servlet Filter which examines the request path of every request and handles each request accordingly. Here is a link that could help get you started, JavaServer Pages (JSP) and JSTL - Access control with JSP
I have now seen a couple of applications that put their internal JSP into WEB-INF/jsp. That seems to do the trick, at least for JSP, and also for Velocity. It does not seem to work for JSF, though.