![]() |
Cloudscape and Security
|
Reference Manual |
Working with User Authentication
OverviewCloudscape provides support for user authentication. User authentication means that Cloudscape authenticates a user's name and password before allowing that user access to the system. When user authentication is enabled (which it is not by default), the user requesting a connection must provide a valid name and password, which Cloudscape verifies against the repository of users defined for the system. Once Cloudscape authenticates the user, it grants the user access to the Cloudscape system but not necessarily access to the database made in the connection request. In the Cloudscape system, access to a database is determined by user authorization. For information, see User Authorization. Cloudscape allows you to provide a repository of users in a number of different ways. For example, you can hook Cloudscape up to an external directory service elsewhere in your enterprise, create your own, use Cloudscape's simple mechanism for creating a built-in repository of users. You can define a repository of users for a particular database or for an entire system, depending on whether you use system-wide or database-wide properties. See Configuring Security for Your Environment for more information. When Cloudscape user authentication is enabled and Cloudscape uses an external directory service, the architecture looks something like that shown in Figure 8-3. Figure 8-3 Cloudscape user authentication using an external service. The application can be a single-user application with an embedded Cloudscape engine or a multi-user application server. Cloudscape always runs embedded in another Java application, whether that application is a single-user application or a multiple-user application server or connectivity framework. A database can be accessed by only one application at a time, so it is possible to deploy a system in which the application in which Cloudscape is embedded, not Cloudscape, handles the user authentication by connecting to an external directory service. For example, Cloudconnector can provide user authentication. In that scenario, Cloudconnector would authenticate the user name and password before granting access to the system in question. It would then grant the user access to the Cloudscape system and would pass the user's name to Cloudscape. Figure 8-4 The application provides the user authentication using an external service. The application can be a single-user application with an embedded Cloudscape engine or a multi-user application server. Enabling User AuthenticationTo enable user authentication, set the cloudscape.connection.requireAuthentication property to true. Otherwise, Cloudscape does not require a user name and password. You can set this property as a system-wide property or as a database-wide property. For a multi-user product, you would typically set it for the system in the cloudscape.properties file for your server, since it is in a trusted environment. NOTE: If you start a Cloudscape system with user authentication enabled but without defining at least one user, you will not be able to shut down the system gracefully. When Cloudscape is running in a connectivity server and user authentication is turned on, stopping the server requires a user name and password. You will need to alter shutdown scripts accordingly. See the Cloudscape Server and Administration Guide for information. Defining UsersCloudscape provides several ways to define the repository of users and passwords. To specify which of these services to use with your Cloudscape system, set the property cloudscape.authentication.provider to the appropriate value as discussed in the appropriate section listed below. Setting the property as a system-wide property creates system-wide users. Setting the property as a database-wide property creates users for a single database only.
NOTE: Shutting down the Cloudscape system (for example, using the shutdown=true form of the database connection URL without specifying a particular database) when user authentication is turned on requires that you define at least one user as a system-wide user. External Directory ServiceA directory service stores names and attributes of those names. A typical use for a directory service is to store user names and passwords for a computer system. Cloudscape uses the Java naming and directory interface (JNDI) to interact with external directory services that can provide authentication of users' names and passwords. In Version 3.0, Cloudscape can use the following services: LDAP Directory ServiceYou can allow Cloudscape to authenticate users against an existing LDAP directory service within your enterprise. LDAP (lightweight directory access protocol), an emerging Internet standard, provides an open directory access protocol running over TCP/IP. An LDAP directory service can quickly authenticate a user's name and password. To use an LDAP directory service, set cloudscape.authentication.provider to LDAP. Examples of LDAP service providers are:
Cloudscape 2.0 has been tested with Netscape Directory Server and Netscape Directory Synchronization Service. Libraries for LDAP User AuthenticationTo use an LDAP directory service with Cloudscape, you need the following libraries in your class path: Cloudscape does not provide these libraries; they are available from JavaSoft on the JNDI page at http://java.sun.com:80/products/jndi/. Use the 1.1.x versions of these libraries, not the 1.2.x versions. You may need to do two separate downloads to obtain all the required libraries. Setting Up Cloudscape to Use Your LDAP Directory ServiceWhen specifying LDAP as your authentication service, you must specify the location of the server and its port number.
cloudscape.authentication.server=godfrey:389 Guest Access to Search for DNsIn an LDAP system, users are hierarchically organized in the directory as a set of entries. An entry is a set of name-attribute pairs identified by a unique name, called a DN (distinguished name). An entry is unambiguously identified by a DN, which is the concatenation of selected attributes from each entry in the tree along a path leading from the root down to the named entry, ordered from right to left. For example, a DN for a user might look like this: cn=mary,ou=People,o=cloudscape.com uid=mary,ou=People,o=cloudscape.com The allowable entries for the name are defined by the entry's objectClass. An LDAP client can bind to the directory (successfully log in) if it provides a user ID and password. The user ID must be a DN, the fully qualified list of names and attributes. This means that the user must provide a very long name. Typically, the user knows only a simple user name (e.g., the first part of the DN above, WilliamS). With Cloudscape, you do not need the full DN, because an LDAP client (Cloudscape) can go to the directory first as a guest or even an anonymous user, search for the full DN, then rebind to the directory using the full DN (and thus authenticate the user). Cloudscape typically initiates a search for a full DN before binding to the directory using the full DN for user authentication. Cloudscape does not initiate a search in the following cases:
For more information, see cloudscape.authentication.ldap.searchFilter in Tuning Cloudscape. Some systems permit anonymous searches; other require a user DN and password. You can specify a user's DN and password for the search with the properties listed below. In addition, you can limit the scope of the search by specifying a filter (definition of the object class for the user) and a base (directory from which to begin the search) with the properties listed below.
To narrow the search, you can specify a user's objectClass.
Performance IssuesFor performance reasons, the LDAP directory server should be in the same LAN as Cloudscape. Cloudscape does not cache the user's credential information locally and thus must connect to the directory server every time a user connects. Connection requests that provide the full DN are faster than those that must search for the full DN. Windows NT UsersNetscape provides LDAP functionality for Windows NT systems with its Netscape Directory Synchronization service, which synchronizes the Windows NT users with the Netscape Directory Server. SSL is recommended in this configuration. RestrictionsCloudscape Version 3.6 does not support LDAP groups. NIS Directory Service Plus (NIS+)Network Information Services Plus (NIS+) is an enhanced version of the NIS name service used on the Sun Solaris and SunOS operating systems. In this system, users are contained in the NIS+ table called passwd.org_dir and groups in the table called group.org_dir. To use an NIS+ directory service, set cloudscape.authentication.provider to NIS+. Libraries for NIS Directory Service Plus User AuthenticationTo use NIS+ directory service with Cloudscape, you need the following libraries in your class path: Cloudscape does not provide these libraries; they are available from JavaSoft on the JNDI page at http://java.sun.com:80/products/jndi/. Use the 1.1.x versions of these libraries, not the 1.2.x versions. You may need to do two separate downloads to obtain all the required libraries. Configuring Cloudscape for NIS+ User AuthenticationYou must set the cloudscape.authentication.server property to JNDI-Specific Properties for External Directory ServicesCloudscape allows you to set a few advanced JNDI properties, which you can set in any of the supported ways of setting Cloudscape properties. Typically you would set these at the same level (database or system) for which you configured the external authentication service. The list of supported properties can be found in Appendix A: JNDI Context Environment in the Java Naming and Direction API at http://java.sun.com:80/products/jndi/docs.html. The external directory service must support the property. Each JNDI provider has its set of properties that you can set within the Cloudscape system. For example, you can set the property java.naming.security.authentication to allow user credentials to be encrypted on the network if the provider supports it. You can also specify that SSL be used with LDAP (LDAPS). User-Defined ClassSet cloudscape.authentication.provider to the full name of a class that implements the public interface COM.cloudscape.authentication.Interface.AuthenticationScheme. By writing your own class that fulfills some minimal requirements, you can hook Cloudscape up to an external authentication service other than LDAP or NIS+. To do so, specify an external authentication service by setting the property cloudscape.authentication.provider to a class name that you want Cloudscape to load at startup. The class that provides the external authentication service must implement the public interface COM.cloudscape.authentication.Interface.AuthenticationScheme and throw exceptions of the type COM.cloudscape.authentication.Interface.AuthenticationException where appropriate. Using a user-defined class makes Cloudscape adaptable to various naming and directory services. A very simple example of a class that implements the interface follows. import COM.cloudscape.authentication.Interface.*; import java.io.FileInputStream; import java.util.Properties; /** * A simple example of a specialized Authentication scheme. * The system property 'cloudscape.connection.requireAuthentication * must be set * to true and 'cloudscape.connection.specificAuthentication' must * contain the full class name of the overriden authentication * scheme, i.e., the name of this class. * * @see COM.cloudscape.authentication.Interface.AuthenticationScheme */ public class MyAuthenticationSchemeImpl implements AuthenticationScheme { private static final String USERS_CONFIG_FILE = "myUsers.cfg"; private static Properties usersConfig; // Constructor // We get passed some Users properties if the //authentication service could not set them as //part of System properties. // public MyAuthenticationSchemeImpl() { } /* static block where we load the users definition from a users configuration file.*/ static { /* load users config file as java properties File must be in the same directory where Cloudscape gets started. (otherwise full path must be specified) */ FileInputStream in = null; usersConfig = new Properties(); try { in = new FileInputStream(USERS_CONFIG_FILE); usersConfig.load(in); in.close(); } catch (java.io.IOException ie) { // No Config file. Raise error message System.err.println( "WARNING: Error during Users Config file retrieval"); System.err.println("Exception: " + ie); } } /** * Authenticate the passed-in user's credentials. * A more complex class could make calls * to any external users directory. * NOTE: AuthenticationException must be thrown upon failure. * * @param userName The user's name * @param userPassword The user's password * @param databaseName The database * @param infoAdditional jdbc connection info. * @exception AuthenticationException on failure */ public voidauthenticateUser(String userName, String userPassword, String databaseName, Properties info ) throws AuthenticationException { /* Specific Authentication scheme logic. If user has been authenticated, then simply return. If user name and/or password are invalid, then raise the appropriate exception: new AuthenticationException.loginFailed(); If the user is not a valid user of the database, then raise: new AuthenticationException.notAValidUserInDatabase (userName, databaseName); For other (exceptional) exception, raise: new AuthenticationException.loginFailed(myExceptionMsg); This example allows only users defined in the users config properties object. Check if the passed-in user has been defined for the system. We expect to find and match the property corresponding to the credentials passed in. */ if (userName == null) // We don't tolerate 'guest' user for now. throw AuthenticationException.loginFailed(); // // Check if user exists in our users config (file) // properties set. // If we didn't find the user in the users config set, then // try to find if the user is defined as a System property. // String actualUserPassword; actualUserPassword = usersConfig.getProperty(userName); if (actualUserPassword == null) actualUserPassword = System.getProperty(userName); if (actualUserPassword == null) // no such passed-in user found // Raise expected exception throw AuthenticationException.loginFailed(); // check if the password matches if (!actualUserPassword.equals(userPassword)) // Raise expected exception throw AuthenticationException.loginFailed(); // Now, let's check if the user is a valid user of the database if (databaseName != null) { /* if database users restriction lists present, then check if there is one for this database and if so, check if the user is a valid one of that database. For this example, the only user we authorize in database DarkSide is user 'DarthVader'. This is the only database users restriction list we have for this example. We authorize any valid (login) user to access the OTHER databases in the system. Note that database users ACLs could be set in the same properties file or a separate one and implemented as you wish. */ // if (databaseName.equals("DarkSide")) { // check if user is a valid one. if (!userName.equals("DarthVader")) // This user is not a valid one of the passed-in // database name. We raise the appropriate // exception expected by Cloudscape. throw AuthenticationException.notAValidDatabaseUser( userName, databaseName); } } // The user is a valid one in this database return; } /** * Returns authentication scheme name string. * Typically a string that succinctly states and identifies * the authentication scheme. * @return authentication scheme name string. **/ public String toString() { return "my authentication scheme"; } } Built-in Cloudscape UsersCloudscape provides a simple, built-in respository of user names and passwords. To use the built-in repository, set cloudscape.authentication.provider to CLOUDSCAPE. Using built-in users is an alternative to using an external directory service such as LDAP. cloudscape.authentication.provider=CLOUDSCAPE You can create user names and passwords for Cloudscape users by specifying them with the cloudscape.user.UserName property. NOTE: These user names are case-sensitive for user authorization. User names are SQL92Identifiers. Delimited identifiers are allowed: cloudscape.user."FRed"=java For more information on user names and SQL92Identifiers, see Users and Authorization Identifiers. NOTE: For passwords, it is a good idea not to use words that would be easily guessed, such as a login name or simple words or numbers. A password should be a mix of numbers and upper- and lowercase letters. Database-Level PropertiesWhen you create users with database-level properties, those users are available to the specified database only. You set the property once for each user. To delete a user, set that user's password to null. -- adding the user sa with password `cloud3x9'
CALL PropertyInfo.setDatabaseProperty(
-- adding the user mary with password `little7xylamb'
-- removing mary by setting password to null System-Level PropertiesWhen you create users with system-level properties, those users are available to all databases in the system. You set the value of this system-wide property once for each user, so you may set it several times. To delete a user, remove that user from the file. You can define this property in the usual ways--typically in the cloudscape.properties file. For more information about setting properties, see Tuning Cloudscape. Here is a sample excerpt from the cloudscape.properties file: # Users definition # cloudscape.user.sa=cloud3x9 cloudscape.user.mary=little7xylamb Properties SummaryTable 8-1 summarizes the various properties related to user authentication.
Programming Applications for Cloudscape User Authentication
Programming the Application to Provide the User and PasswordIn the DriverManager.getConnection call, an application can provide the user name and password:
NOTE: The password is not encrypted.When you are using Cloudscape in the context of a server framework, the framework should be responsible for encrypting the password across the network. If your framework does not encrypt the password, consider using SSL. Cloudconnector does not encrypt a password unless you use SSL. For information about the treatment of user names within the Cloudscape system, see Users and Authorization Identifiers. Login Failure ExceptionsIf user authentication is turned on and a valid user name and password are not provided, SQLException XJ006 is raised. |
||||||||||||||
|
![]() Cloudscape Version 3.6 For information about Cloudscape technical support, go to: www.cloudscape.com/support/.Copyright © 1998, 1999, 2000 Informix Software, Inc. All rights reserved. |