SASL defines a protocol for authentication and optional establishment of a security layer between client and server applications. SASL defines how authentication data is to be exchanged but does not itself specify the contents of that data. It is a framework into which specific authentication mechanisms that specify the contents and semantics of the authentication data can fit. SASL is a standard defined by RFC 2222. SASL is used by protocols such as the Lightweight Directory Access Protocol, version 3 (LDAP v3) and the Internet Message Access Protocol, version 4 (IMAP v4) to enable pluggable authentication. Instead of hardwiring an authentication method into the protocol, LDAP v3 and IMAP v4 use SASL to perform authentication via various SASL mechanisms. Java SASLJava SASL was introduced in the release of J2SE 5.0. It defines Java API mechanisms with an authentication mechanism-neutral solution so the application that uses the API need not be hard-wired to use any particular SASL mechanism. The API facilitates both client and server applications. It allows applications to select the mechanism to use based on desired security features, such as whether they are susceptible to passive dictionary attacks or whether they accept anonymous authentication. The Java SASL API supports developers creating their own custom SASL mechanisms. SASL mechanisms are installed by using the JCA. SASL provides a pluggable authentication solution and security layer for network applications. It works together with other API solutions such as JSSE and Java GSS. For example, an application can use JSSE for establishing a secure channel and then use SASL for client, username/password-based authentication. Similarly, SASL mechanisms can be layered on top of GSS-API mechanisms to support the SASL GSS-API/Kerberos v5 mechanism that is used with LDAP. Java SASLAPI OverviewThe Java SASL API has two interfaces, SaslClient and SaslServer, that represent client-side and server-side mechanisms, respectively. The application interacts with the SASL mechanisms using a challenge-response protocol with byte arrays that represent the challenges and responses. The server-side mechanism iterates, issuing challenges and processing responses, until it is satisfied, while the client-side mechanism iterates, evaluating challenges and issuing responses, until the server is satisfied. The application that is using the mechanism drives each iteration. That is, it extracts the challenge or response from a protocol packet and supplies it to the mechanism. Then it puts the response or challenge returned by the mechanism into a protocol packet and sends it to the peer. In many protocols that use SASL, the server advertises (either statically or dynamically) a list of SASL mechanisms that it supports. The client then selects one of these based on its security requirements. The Sasl class is used for creating instances of SaslClient and SaslServer. Here is an example of how an application creates an SASL client mechanism using a list of possible SASL mechanisms. Let's take a look at some code fragments that show how to use Java SASL API mechanisms. An application or library can locate and instantiate an SASL server or client using the Sasl class. For example (see Example 4-48), to locate and instantiate an SASL client, you would proceed as follows. Example 4-48. Creating a SASL clientSaslClient sc = Sasl.createSaslClient(mechanisms,authorizationId, protocol, serverName, props,callbackHandler); Then the SASL Client can proceed for LDAP authentication (see Example 4-49). Example 4-49. Using the SASL client for LDAP authentication// Get initial response and send to server byte[] response = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null); LdapResult res = ldap.sendBindRequest(dn, sc.getName(), response); while (!sc.isComplete() && (res.status == SASL_BIND_IN_PROGRESS || res.status == SUCCESS)) { response = sc.evaluateChallenge(res.getBytes()); if (res.status == SUCCESS) { // we're done here; // Don't expect to send another BIND if (response != null) { throw new SaslException("Protocol error"); } break; } res = ldap.sendBindRequest(dn, sc.getName(), response); } if (sc.isComplete() && res.status == SUCCESS) { String qop = (String) sc.getNegotiatedProperty(Sasl.QOP); if (qop != null && (qop.equalsIgnoreCase("auth-int") || qop.equalsIgnoreCase("auth-conf"))) { // Use SaslClient.wrap() and SaslClient.unwrap() // for future // communication with server ldap.in = new SecureInputStream(sc, ldap.in); ldap.out = new SecureOutputStream(sc, ldap.out); } } Similarly, a server creates an SASL server as shown in Example 4-50. Example 4-50. Creating a SASL serverSaslServer ss = Sasl.createSaslServer(mechanism, protocol, serverName, props, callbackHandler); The SASL server can proceed for authentication (i.e., assuming the LDAP server received an LDAP BIND request containing the name of the SASL mechanism and an (optional) initial response). The server will initiate authentication as follows (see Example 4-51). Example 4-51. SASL server for authentication after LDAP BIND requestwhile (!ss.isComplete()) { try { byte[] challenge = ss.evaluateResponse(response); if (ss.isComplete()) { status = ldap.sendBindResponse(mechanism, challenge, SUCCESS); } else { status = ldap.sendBindResponse(mechanism, challenge, SASL_BIND_IN_PROGRESS); response = ldap.readBindRequest(); } } catch (SaslException e) { status = ldap.sendErrorResponse(e); break; } } if (ss.isComplete() && status == SUCCESS) { String qop = (String) sc.getNegotiatedProperty(Sasl.QOP); if (qop != null && (qop.equalsIgnoreCase("auth-int") || qop.equalsIgnoreCase("auth-conf"))) { // Use SaslServer.wrap() // and SaslServer.unwrap() for future // communication with client ldap.in = new SecureInputStream(ss, ldap.in); ldap.out = new SecureOutputStream(ss, ldap.out); } } Installing Java SASLThe SASL security providers provide SASL mechanism implementations. Each provider implementation may support one or more SASL mechanisms that can be registered with JCA. By default in J2SE 5.0, the SunSASL provider is automatically registered as a JCA provider in the Java Security Properties file at ($JAVA_HOME/jre/lib/security/java.security). security.provider.7=com.sun.security.sasl.Provider The Sun Java SASL provider (SunSASL) provides support for several SASL mechanisms used in popular protocols such as LDAP, IMAP, and SMTP. This includes support for the following client and server authentication mechanisms as well: Client Mechanisms
Server Mechanisms
For more information about using Java SASL, refer to http://java.sun.com/j2se/1.5.0/docs/guide/security/sasl/sasl-refguide.html. |