I'm new here, so please be patient with me...
I'm using tomcat 6.x and I want to secure a folder in webapps with a security-constraint. When I'm calling the web server via IP-adress like http://xx.xxx.xx.xx/...... the login is working fine with firefox 3.6 and IE8. When I'm configuring a hostname and calling the web server like http://hostname/... the login works fine with firefox 3.6, but don't work with IE8.
The error with IE8 in detail: it seems the login works and i arrive to the welcome page witch is defined in the security-constraint. But when I click on a link on this page, to a page which is a folder deeper in the folder-tree, tomcat bypass me to the login page again. I can repeat this as long as I want, it's an infinite loop.
Did anybody knows this problem?
Here my web.xml with the security-constraint:
Thanks for helping me.
On your other part, it sounds like you're running your own login service. Security constraints only work when you let Tomcat run the login service. That means you don't login through a login URL. Instead, accessing a constrained URL (as mentioned above) will cause Tomcat to put the access request on hold, display and process the login page that you defined to web.xml, and then resume the original access request (assuming successful login). You will not be prompted to login again unless you invalidate (destroy) your HttpSession object, which is where Tomcat stores the internal information about your login state. Tomcat will automatically create an HttpSession when you login.
I've seen you post this statement more than a few times. I never understand what you are talking about when you say that a folder is a resource, but that security constraints apply to URLs.
URL = Uniform "Resource" Locator.
From the Java EE 5 Tutorial:
"A security constraint is used to define the access privileges to a collection of resources using their URL mapping"
Maybe I'm wrong, but this suggests what you are saying is incorrect.
The Java Servlet specification defines the request URI as the part of a URL after the host name and port. For example, let’s say you have an e-commerce site with a browsable catalog that you would want anyone to be able to access, and a shopping cart area for customers only. You could set up the paths for your web application so that the pattern /cart/* is protected but nothing else is protected. Assuming that the application is installed at context path /myapp, the following are true:
http://localhost:8080/myapp/index.jsp is not protected.
http://localhost:8080/myapp/cart/index.jsp is protected.
A user will not be prompted to log in until the first time that user accesses a resource in the cart/ subdirectory.
Is this saying that index.jsp is located in the root of /myapp and also in the /cart subdirectory?
There are 2 views of a WAR.
One view is the developer's view. The WAR is a ZIP (JAR) file when distributed according to the J2EE spec. Tomcat allows working with an unzipped (exploded) copy of the WAR, but other than how it lives on the server's disk drive, the difference is no difference.
The other view is the application user's view. The important thing to remember here is an old familiar mantra of mine:
A web server is not a file server.
You cannot use a filesystem open method in code running on the client machine to access resources that are in the server machine. You cannot use any of the filesystem function calls, in fact. To access a web resource, the client must open a pair of network sockets, one for sending, one for receiving. The sending socket's destination is the web server, including a port number (80 for standard WWW, 8080 for default Tomcat, 443 for SSL, and so forth). Once the connection is open, the client must send a text data stream that conforms to a rigidly-defined specification. Specifically, the HTTP 1.1 spec as defined in the HTTP RFC, or one of the related supported RFC's (such as HTTP 1.0). The first line of that stream includes a command (generally GET or POST) and a Uniform Resource Locator (URL).
On the receiving side, the server (Tomcat) listens for connection requests on its ports (8080, 8443, and so forth). When a request is made, it opens up a receiving socket and accepts the HTTP data stream coming from the client. It parses the data stream, starting with the URL. The URL is dissected to determine a webapp context, and, if the context matches one of the contexts defined as webapps to Tomcat, the data stream is switched over to application request processing.
Before the data actually hits the webapp, however, it goes through several intermediaries, both standard and optional. In Tomcat, typically these are Valves and you can even write your own, if needed. One of those intermediaries is the container-managed authorization mechanism, which will get involved if the webapp's web.xml indicates that container managed authentication and authorization is in use.
The container-managed authorization mechanism does a pattern match against the incoming URL, stripped of the server/context parts. The patterns it uses are those which were supplied in the webapp's web.xml. If there's a hit, the authorization mechanism first checks to see if the requester is logged in. If not, the whole request is sidelined, the login form defined in web.xml is posted back to the requester, and the requester interacts with the login process. Once logged in, the original request is pulled back off the sidelines and proceeds as though nothing had happened.
Well, almost nothing. Once a user is logged in, he/she/whatever has an associated set of security roles. The URL pattern that matches the original URL request also specifies a set of roles. If there's an intersection between the two, the request is passed down the processing pipeline and eventually to the webapp. If there isn't a match between user roles and authorized roles, the request is rejected on the spot, a "forbidden" error is raised, and the request never gets anywhere near the webapp (other than maybe having a custom 403 page displayed).
When the request reaches the webapp proper, it's going to be matched up by URL pattern to see if it matches a servlet's URL pattern defined in web.xml or an implicit pattern definition made by compiling a JSP to product a corresponding JSP servlet. If there's a match, the request - which at this point is going to have been distilled into a J2EE Http(Servlet)Request - enters the servlet's service() method which typically routes it to a doGet or doPost method.
It's been a long trip. but at last the client request has arrived at the developer-written code or some facsimile thereof. Note that at no time up to now have I referred to directories or even folders. The URL is simply a text string containing various amusing bits of information. The security manager doesn't look at the URL from the point of view of a filesystem architecture, only as a string to be sliced and diced and used as a basis for applying rules digested from the appropriate application's web.xml file.
The confusing thing about URLs and resources is that resources are files and directories (folders) in a virtual filesystem based on the WAR. But webapp clients cannot access resources directly, because a web server is not a file server. Despite the fact that URLs typically have lots of slashes in them, URLs are strings. It's up to the webapp to interpret those strings. For example, in JSF, if I define a URL pattern such as "/faces/*" and bind it to the FacesServlet, Tomcat will route any URL requests containing the "/faces/" segment immediately following the host/port/context part of the URL to the FacesServlet. The FacesServlet will then dissect the incoming URL, pull off the View name and use that to look up the resource that defines the View. This is how a request like "/faces/secured/SecureIndex.jsp" can be used to serve up a View whose template is stored as a WAR resource under "/secured/SecureIndex.jsp". Or, if you prefer the "*.jsf" URL pattern, how "/secured/SecureIndex.jsf is resolved by using the WAR's View template resource "/secured/SecureIndex.jsp".
It's also how you can accept URLs that correspond to no file at all and return completely dynamic content such as generated charts and other graphics or "on-the-fly" PDF's.
Finally, at long last, the response is returned to the client. Assuming that the incoming URL passed the security system.
Hopefully this makes the distinction between URL paths and WAR resource paths a little clearer and why it is that container security cannot protect WAR resources directly, but only URLs that would attempt to access them. Making sure that the only URLs that access them are protected is up to you.
leo donahue wrote:
Is there another way to access resources directly on the server, from the client, without a using a URL?
Yes. Install file server software and make a Windows Networking and/or NFS share out of the resources.
Of course doing that for a WAR would expose the WAR's internal software components to the unwashed masses, and exposing a filesystem share to the open Internet is simply begging for trouble. And the client would have to have a network filesystem client package installed, although for Windows Networking, that's part of the standard OS package.
However, if you want to use HTTP to get at a resource, you have to play by HTTP rules.
Just as well. We've got enough security problems as it is.