Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Building Java Enterprise Applications Volume I: Architecture phần 5 pot
Nội dung xem thử
Mô tả chi tiết
Building Java™ Enterprise Applications Volume I: Architecture
105
// Create the objectclass to add
Attribute objClasses = new BasicAttribute("objectClass");
objClasses.add("top");
objClasses.add("person");
objClasses.add("organizationalPerson");
objClasses.add("inetOrgPerson");
// Assign the username, first name, and last name
String cnValue = new StringBuffer(firstName)
.append(" ")
.append(lastName)
.toString( );
Attribute cn = new BasicAttribute("cn", cnValue);
Attribute givenName = new BasicAttribute("givenName", firstName);
Attribute sn = new BasicAttribute("sn", lastName);
Attribute uid = new BasicAttribute("uid", username);
// Add password
Attribute userPassword =
new BasicAttribute("userpassword", password);
// Add these to the container
container.put(objClasses);
container.put(cn);
container.put(sn);
container.put(givenName);
container.put(uid);
container.put(userPassword);
// Create the entry
context.createSubcontext(getUserDN(username), container);
}
Deleting users, or any type of subcontext, is a much simpler task. All you need to do is
identify the name that the subcontext is bound to (in this case, the user's DN), and invoke the
destroySubcontext( ) method on the manager's DirContext object. Additionally, while
the method still throws a NamingException, it should trap one specific problem, the
NameNotFoundException. This exception is thrown when the requested subcontext does not
exist within the directory; however, because ensuring that the DN for the user specified
doesn't exist is the point of the deleteUser( ) method, this problem is ignored. Whether the
specified user is deleted, or did not exist prior to the method call, is irrelevant to the client.
Add the deleteUser( ) method shown here to your source code:
public void deleteUser(String username) throws NamingException {
try {
context.destroySubcontext(getUserDN(username));
} catch (NameNotFoundException e) {
// If the user is not found, ignore the error
}
}
Any other exceptions that might result, such as connection failures, are still reported through
the NamingException that can be thrown in the method.
With these two methods in place, all user manipulation can be handled. You will notice,
though, that I haven't discussed any methods to allow user modification. It would seem that
without these methods, a user's password could not be changed, and their first or last name
Building Java™ Enterprise Applications Volume I: Architecture
106
could not be updated. However, this is not the case. Instead of providing a method to allow
those operations, it is easier to require components using the manager to delete the user and
then re-create that user with the updated information. While this might seem a bit of a pain,
keep in mind that you will have a component that handles all user actions and abstracts both
this manager and the entity beans from the application layer. In other words, ease of use is not
the primary concern in the manager. The advantage in not providing update methods is that it
keeps the manager clear and simple; additionally, for the sake of only four attributes (if you
count the username, which should not change anyway), update methods are simply not worth
the trouble.
6.2.3.3 Authenticating the user
The last task the manager needs to perform that directly involves users (and only users; I'll
look at working with users and other objects together a little later) is authentication. When a
user first accesses the Forethought application, he or she will eventually try to access
protected resources. At that point, authentication needs to occur; permissions and groups can
be looked up, but first the user must provide a username and password. These, of course, must
be pushed back to the directory server, and the manager should let the client component know
if the username and password combination is valid.
The code for this is a piece of cake; in fact, you've already written it! Remember that the
getInitialContext( ) method took a username and password in addition to a hostname
and port number. You can use this same method with the username and password supplied to
the new authentication method, isValidUser( ). The method then simply catches any
exceptions that may occur. If there are no errors, a successful context was obtained and the
user is valid; if errors occur, then problems resulted from authentication, and the user is
rejected.
Any exception results in the isValidUser( ) method returning false,
indicating that a login has failed. In a strict sense, this can return some
false negatives; if the connection to a directory server has dropped, for
example, the method returns false. This is somewhat deceptive, and in
an industrial-strength application, a reconnection might be attempted in
this case. However, in even medium-sized applications, a downed
directory server will cripple an application anyway, so denying a user
access is still the right thing to do. In other words, while the false
result may not indicate a failed authentication, it does indicate that the
user should not be allowed to continue.
You also need to be sure that you don't overwrite the existing DirContext instance, the
member variable called context in the LDAPManager class, with any returned DirContext
instance obtained in this method. If that happened, the credentials used in this method would
determine what actions could be performed by the other methods. Few, if any, users other
than the Directory Manager would be able to add, delete, and modify objects in the directory.
You could end up with a very subtle bug that causes all operations on the directory to