This document has the following sections:
In distributed systems, servers normally need to know who their clients are in order to ensure that they are only given access to appropriate data and functionality. This concept should be familiar to most users, because even on today's lowest security desktop systems a "login" is required. The network acts as a timeshared computer, with some of the sharing controlled physically (personal workstations or computers) and other sharing, on servers, controlled by security features of the network services.
For example, data access protocols like HTTP, FTP, and NFS all provide the ability to deny access to users which attempt to access data which they are not intended to see. Mail services such as SMTP, POP3, and IMAP4 also require users to authenticate themselves, and deny users access to other users' mailboxes. There are other examples too; authenticating users is the norm, rather than the exception, with network services.
This document describes some of the tools which are provided as part of
the JavaServer Toolkit, to control how server resources are shared. These
focus on the
realm package, which is used to structure identification of users and
groups. In conjunction with an enhanced version of the Access Control List
(ACL) interfaces in the java.security.acl
package, the server
toolkit supports standard identity-based access controls. In particular,
this document describes:
NOTE: These programming interfaces are subject to change.
In the JavaServer Toolkit, users (and their groups) are authenticated and identified using objects whose type is sun.server.realm.Realm. Realms are used by programs residing in a server. The server is normally expected to be privileged enough to administer the realm. However, realms can also be "read-only" in the sense that not all servers will have privileges to administer such mission-critical databases. Also, not all components in within a server will be in a "sandbox" which grants them administrative privileges.
In addition to the instance-specific methods presented in the rest of this document, there are two static ("class") methods on realms:
Realm.list()
returns a vector of the realm names
recognized by this server.
Realm.get(String name)
returns a named realm.
There can be many kinds of realms:
Realms all provide the same core functionality. Namely, persistent access to:
In a later release of the JavaServer Toolkit, each kind of realm will be able to supply its own administrative user interface. This will allow the realms to expose features which some realms support, and others don't:
In the initial release of the JavaServer Toolkit there are only two kinds of realms which are accessible. One is a simple "shared password" realm, suitable for small user communities where the risks associated with server break-in are low. (The passwords are essentially stored in plain text.) The other is the "UNIX" realm, for sites with existing large UNIX user communities that are securely administered.
Most access control is geared around granting (or denying) access to
clients authenticated using the
realm.User
interface. Users are principals, and fit within the standard
java.security
framework. Realms implement the following APIs
related to users. Note that creation of user objects is not a standard
operation, since different
realms require different information to be able to create users:
Realm.getUserNames()
returns an enumeration of all
the names of users in this realm.
Realm.getUser(String name)
returns the User object
corresponding to that particular name.
Realm.deleteUser(String name)
deletes the User object
corresponding to that particular name. Users are java.security.Principal objects which are associated with the following additional data:
An attribute of particular interest is the home directory used to provide access to that user's personal file storage. This attribute is a URL. Another attribute is defined for the user's fullname, which can be important in many user interaction tasks.
Different authentication schemes require different protocols between the user and the server. A given realm normally supports the same sort of protocol(s) for all its users. Common examples of such protocols include:
Passphrase systems are widely used despite some widely acknowledged problems, which are most severe when users use short "pass words".
The SharedPasswordRealm supports passphrase authentication, and also some simple challenge response protocols. When used with HTTP, it supports both Basic and Digest authentication. (Digest authentication is a simple challenge/response protocol.)
At this time, work is still being performed to support other challenge/response schemes and public key authentication through this Realm framework.
This code sample shows how to authenticate a user using a shared password realm. Note that possession of a User or Principal object doesn't signify anything in general, although a non-null "User" object indicates successful authentication in this API.
User passwordAuthenticateUser ( SharedPasswordRealm r, String userName String passPhrase ) { User u = r.getUser (userName); PassphraseAuth u2 = (PassphraseAuth) u; if (u.authenticate (passPhrase)) return u; else return null; }
Groups are used to simplify many access control policies. Users are given membership in groups, and policies are established saying which groups have access to which resources. This reduces the number of policies that need to be administered, and can reduce the rate of errors implementing access control policies.
Groups are a standard part of the JDK 1.1 interfaces; the java.security.acl.Group class defines the functionality which realms expose. Operations to add and delete group members automatically update the persistent state of the group.
Realms implement the following APIs related to groups. Note that interfaces to create groups are defined in a standard form here, since (unlike the situation with users) there does appear to be a least common denominator for group manipulation.
Realm.getGroupNames()
enumerates the names of a
realm's groups.
Realm.getGroup(String name)
returns a given group
Realm.makeGroup(String name)
creates a given group
Realm.deleteGroup(String name)
deletes a given group
Note that the UNIX realm does not at this time implement these operations. There are several technical reasons for this, some of which are amenable to fixing over time:
Access Control Lists are objects which encapsulate access control policies. They can be named, so that many resources can share the same policy. As with naming groups, this reduces the number of policies that need to be administered, and can reduce the rate of errors implementing access control policies.
ACLs are a standard part of the JDK 1.1 interfaces; the java.security.acl.Acl class defines the functionality which realms expose. Operations to add and delete ACL entries automatically update the persistent state of the ACL.
Realms implement the following APIs related to ACLs. Note that interfaces to create acls are defined in a standard form here, since (unlike the situation with users) the ACL API is somewhat amenable to subsetting for realms that do not support the full ACL semantics. (Consider what would be involved in fitting POSIX or NT ACLs into this framework.)
Realm.getAclNames()
enumerates the names of the
realm's ACLs.
Realm.getAcl(String name)
returns the named ACL
Realm.makeAcl(String name, Principal owner)
creates a
named ACL with a given owner.
Realm.deleteAcl(String name)
deletes the named ACL
Two methods are defined to support realm integrity:
Realm.verifyNotInPolicies(Principal p)
verifies that
the principal is not used in a group or ACL, so that it is safe to
delete records of that principal (user or group).
Realm.getDefaultAclOwner()
returns the default
owner of ACLs in that realm; the name of this owner will not be
the same in all realms.
There is larger document on ACLs and their use with Realms in the JavaServer Toolkit.