That isn't appropriate for every type of site, so now I'll show how to allow people to register at your site and create a login and password specific for your site.
I'd planned on using Spring Security for this, so that the authentication would be robust. But, Spring Security has some dependencies on the Spring framework. Supposedly getting it to work without Spring is possible, but not knowing either product it probably won't happen in the limited amount of time I have available (sorry for those of you searching for how to do just that).
I do, by the way, highly recommend Spring for industrial strength applications built on Java servlets. It just isn't appropriate for the class that I'm teaching. So, the authentication we'll roll here won't be industrial grade. But it'll be a start.
Let's talk for a moment about the characteristics of a good authentication mechanism.
First, it must be impossible to fool. For example, an authentication mechanism that simply avoided displaying members only links to non-members would not prevent non-members from typing those links in directly. The server must authenticate on any restricted page load.
Second, it must be easy to use. The more places we have to touch to implement authentication for a page, the higher the chance that we'll get it wrong. In particular, if we have to write Java code for each page we want protected, the chances are good that we'll get it wrong sooner or later.
We'll use Java Servlet filters to accomplish this. A filter is basically a piece of Java code that is run before a servlet is run. The filter can allow the servlet to run, or it can display a page itself and block the servlet. This happens without adding code to the servlet itself.
First step is to set up our web.xml file to use the filter (okay, so we haven't written the filter yet, but editing web.xml is the easy part so we'll get it out of the way). Add something like the following to your web.xml:
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>omega.server.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/members/*</url-pattern>
</filter-mapping>
This is like registering a servlet, in that you specify a URL pattern that triggers the filter. In my case, I used /members/*. This means that any URL under the members directory will trigger the filter. This will require changing my servlet URL mappings around a bit, so that any page that should be restricted to logged in users is mapped under /members, and any page that should be visible to anyone is not. So far for me, that's basically just the ProfileServlet, but I'll make a mental note to put future members only pages under /members.
Now we have to write the AuthenticationFilter class. This is similar to writing a servlet. Create a new class in your server package. There's no superclass for this one, but you will implement an interface. So in the new class dialog, click on the Add button to the right of the (empty) interface list, and type in Filter. You want the javax.servlet.Filter interface.
You'll get some Java code that leaves stubs for three methods: init, destroy, and doFilter. The primary purpose of the init is to save off the FilterConfig passed in, so create a private data member for doing that:
private FilterConfig filterConfig = null;
public void init(FilterConfig arg0) throws ServletException {
filterConfig = arg0;
}
You may not need that FilterConfig instance, but it can be used to get the ServletContext of the servlet that you're filtering.
The actual work of authentication will be done in the doFilter method. Here's the basic idea (not working code, but algorithm):
if (user authenticates correctly)
chain.doFilter(request, response);
else
{
User the response argument to generate error output, or redirect to a login form
}
So calling chain.doFilter passes the request on to the next filter in the chain, meaning that the AuthenticationFilter is happy with the request. If authentication fails, do something other than calling chain.doFilter.
The details of pulling a user's password from the datastore and comparing it to one passed into the HTTP request we've already covered. You should also be able to write the registration form and servlet to allow users to create their user account in the first place (and you can do verification of their email, too). You should also know what you need to know to have a "I forgot my password" link that will email a new password to them.
The one bit that we do still need to cover is storing passwords in an encrypted form. Storing user's passwords in plain text is bad form, so we won't do it.
Next post, encrypting passwords.