8.3. Handling All Security Programmatically

Declarative security (Chapter 7) offers a number of advantages to the developer. Chief among them is the fact that individual servlets and JSP pages need no security-conscious code: the container (server) handles authentication in a manner that is completely transparent to the individual resources. For example, you can switch from form-based authentication to BASIC authentication or from regular HTTP connections to encrypted HTTPS connections, all without any changes to the individual servlets or JSP pages.

Even when you want a bit more control than just “access allowed” or “access denied,” it is convenient to let the server maintain and process the usernames and passwords, as discussed in Section 8.1.

However, the convenience of container-managed security comes at a price: it requires a server-specific component. The method for setting up usernames, passwords, and user roles is not standardized and thus is not portable across different servers. In most situations, this disadvantage is outweighed by the faster and simpler servlet and JSP development process that results from leaving some or all of the authorization tasks to the server. In some cases, however, you might want a servlet or JSP page to be entirely self-contained with no dependencies on server-specific settings or even web.xml entries. Although this approach requires a lot more work, it means that the servlet or JSP page can be ported from server to server with much less effort than with container-managed security. Furthermore, it lets the servlet or JSP page use username and password schemes other than an exact match to a preconfigured list.

HTTP supports two varieties of authentication: BASIC and DIGEST. Few browsers support DIGEST, so I’ll concentrate on BASIC here.

Here is a summary of the steps involved for BASIC authorization.

1.
Check whether there is an Authorization request header. If there is no such header, go to Step 5.

2.
Get the encoded username/password string. If there is an Authorization header, it should have the following form:

Authorization: Basic encodedData
							

Skip over the word Basic —the remaining part is the username and password represented in base64 encoding.

3.
Reverse the base64 encoding of the username/password string. Use the decodeBuffer method of the BASE64Decoder class. This method call results in a string of the form username:password. The BASE64Decoder class is bundled with the JDK; in JDK 1.3 it can be found in the sun.misc package in jdk_install_dir/jre/lib/rt.jar.

4.
Check the username and password. The most common approach is to use a database or a file to obtain the real usernames and passwords. For simple cases, it is also possible to place the password information directly in the servlet. In such a case, remember that access to the servlet source code or class file provides access to the passwords. If the incoming username and password match one of the reference username/password pairs, return the page. If not, go to Step 5. With this approach you can provide your own definition of “match.” With container-managed security, you cannot.

5.
When authentication fails, send the appropriate response to the client. Return a 401 (Unauthorized) response code and a header of the following form:

WWW-Authenticate: BASIC realm="some-name" 

This response instructs the browser to pop up a dialog box telling the user to enter a name and password for some-name, then to reconnect with that username and password embedded in a single base64 string inside the Authorization header.

If you care about the details, base64 encoding is explained in RFC 1521. To retrieve RFCs, start at http://www.rfc-editor.org/ to get a current list of the RFC archive sites. However, there are probably only two things you need to know about base64 encoding.

First, it is not intended to provide security, since the encoding can be easily reversed. So, base64 encoding does not obviate the need for SSL (see Section 7.5) to thwart attackers who might be able to snoop on your network connection (no easy task unless they are on your local subnet). SSL, or Secure Sockets Layer, is a variation of HTTP where the entire stream is encrypted. It is supported by many commercial servers and is generally invoked by use of https in the URL instead of http. Servlets can run on SSL servers just as easily as on standard servers, and the encryption and decryption are handled transparently before the servlets are invoked. See Sections 7.1 and 8.6 for examples.

The second point you should know about base64 encoding is that Sun provides the sun.misc.BASE64Decoder class, distributed with JDK 1.1 and later, to decode strings that were encoded with base64. In JDK 1.3 it can be found in the sun.misc package in jdk_install_dir/jre/lib/rt.jar. Just be aware that classes in the sun package hierarchy are not part of the official language specification and thus are not guaranteed to appear in all implementations. So, if you use this decoder class, make sure that you explicitly include the class file when you distribute your application. One possible approach is to make the class available to all Web applications on your server and then to explicitly record the fact that your applications depend on it. For details on this process, see Section 4.4 (Recording Dependencies on Server Libraries).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.107.210