Custom Development with Novell iChain 1.5
Articles and Tips: article
Senior Software Engineer
Novell Developer Labs
sjohns@novell.com
01 Apr 2001
One of the hottest new technologies to come out of Novell recently is iChain. Novell iChain is a directory infrastructure that provides a common security and management base for integrating customers' Internet-based business applications and creating an eBusiness foundation. This AppNote discusses the issues and solutions dealing with custom development in the Novell iChain 1.5 eBusiness environment.
Introduction to iChain
Using eDirectory as the core repository for identity profiles, authentication methodologies, and data access controls, your customers' identity relationships and user security can be managed at the network level rather than application to application. This feature elevates the value of the data from being constrained to a specific application to being relevant across multiple applications via the Internet. We call the framework that provides these services 'iChain.'
iChain is not positioned as a "red box" product, but as a consulting "solution." This means that iChain sales will most likely involve either Novell or third-party consulting, and focused customization is required to suit individual business needs.Therefore, iChain should be viewed as a framework within which custom development is a requirement for use. This AppNote addresses this need for custom development.
Business Need for iChain
There are many reasons why iChain has already attracted much attention and excitement even before the product has been released. The core reasons relate to addressing the critical business needs of using the power of NDS to securely integrate existing Web and eBusiness infrastructures.
Here are some examples of the types of business needs iChain is designed to address:
You or your customer already have NDS eDirectory, and you want to exploit the value of your existing directory infrastructure by making the directory content and security available to your eBusiness Web applications.
You or your customer do not yet have NDS eDirectory, but you want to take advantage of the security, reliability, and management capabilities that eDirectory provides by introducing NDS into your existing (or new) Web application environment.
Customers are tired of having to develop custom authentication services for each of their different Web applications. They want one network-wide authentication infrastructure that all Web applications can "plug in" to and take advantage of.
The solution for each of these eBusiness needs is Novell iChain. Basically, iChain allows you to "directory-enable" your Web sites and Web services. Because iChain is based on eDirectory, it has the capability to furnish directory attributes to applications that use standard Internet protocols, thereby directory-enabling your existing applications even if they do not talk directly to the directory. As a result, iChain provides a common layer of security and management for all eBusiness applications on your site. In other words, your Web applications are alleviated of the burden of having to perform custom authentication!
iChain Feature Overview
Here is a quick overview of the features iChain provides:
Web Authentication to any LDAP v3-compliant directory
Role-based authorization
Web-based Single Sign-On
Contextless login
Secure, scalable, reliable, and distributed Directory store
Granularity of security: eDirectory provides the capability to govern rights down to the attribute-level of an object
True "directory-enabling" of your existing Web applications
Reverse-proxy acceleration of your Web sites
SSL-izer secure connections for your Web services
Depending on how you plan to use iChain, your Web developers may be able to take full advantage of the directory without having to know anything about NDS programming.
iChain Custom Development
Most implentations of iChain will require some level of custom development. Some will require very minor development, while others will require extensive custom development. In either case, at least four types of services will likely be addressed by any development work:
Authorization Header extraction and decoding
Object-level Access Control (OLAC) parameter extraction
User self-registration
User account modification
This AppNote covers these four types of services by examining the following six Java servlets:
iChainAuthHeader.java
iChainOLAC.java
iChainBeanRegister.java (user self-registration via Novell Beans)
iChainBeanModify.java (user account modification via Novell Beans)
iChainLDAPRegister.java (user self-registration via JNDI/LDAP)
iChainLDAPModify.java (user account modification via JNDI/LDAP)
Note: The full source code for these servlets is available for download from the "Downloads" section on the AppNotes Web site at: http://developer.novell.com/research/
This AppNote assumes that you have already set up an iChain 1.5 environment and are familiar with the iChain 1.5 configuration issues. This article focuses on the development aspects of iChain rather than on configuration or administration.
iChain 1.5 Architecture
Before we look at our first servlet, it is helpful to understand the basic iChain architecture. A minimal iChain implementation requires three servers: the iChain 1.5 ICS Proxy Server appliance, the dedicated NDS Authorization Server, and at least one Web Server (see Figure 1).
The architecture of a minimal iChain implementation.
The iChain ICS Proxy Server is a high-performance hardware appliance designed specifically for use in the iChain environment. It provides the reverse-proxy cache acceleration and SSL-izer security enhancements to your Web server. It is also the server that runs the authentication and authorization engine for your Web Server.
The NDS Authorization Server can run on any server platform on which NDS eDirectory 8.5 is supported: NetWare, Windows NT/2000, Sun Solaris, and so on.
The Web Server can be an existing Web server or a new Web server. Any Web server platform is supported by iChain. Note that the Java servlets we will describe in this AppNote run on the Web Server.
Authorization Header Extraction and Decoding
While the NDS authorization server is the "data store" for the directory, the actual authorization engine modules for iChain are run from the proxy server. The iChain proxy server fronts your Web server, which is on a private network that is not publicly available. When a client requests access to a private resource on your Web server (via the client"s browser), the iChain proxy server intercepts this request and requires the user to log in, as shown in Figure 2. (If the user session is requesting a public resource, the user won"t be prompted to log in).
When a user requests access to a private Web resource, the user is required to log in via this iChain login page.
When a user requests access to a private Web resource, the user is required to log in via this iChain login page.
After the user enters his or her username and password and clicks the Login button, the iChain Proxy Server contacts the NDS Authorization Server to verify the user's credentials via the directory. Once a user is successfully authenticated, the iChain Proxy Server sets a volatile cookie on that user session and also injects the user's credentials (username and password) into the 'Authorization' section of the HTTP header. It then passes this user session on to the Web Server. The volatile cookie that the iChain proxy sets keeps the user authenticated for subsequent accesses to Web resources that that user has privileges to.Before the iChain Proxy Server actually injects the user's credentials into the HTTP header, those credentials are base64 encoded. Note that this is not encryption-it is 'encoding' and is standard practice for credentials passed in the HTTP header so as to not pass the credentials in plain-text. As an example, the actual base64-encoded Authorization information that is passed from the iChain Proxy Server to your Web Server might look like the one shown in Figure 3.
The user's credentials are encoded before being passed on to the Web Server to prevent the credentials from being transmitted in plain-text.
What this means is that your Web Server will have to decode the authorization header in order to know the identity of the user who is requesting resources from the Web Server. In many cases, the Web Server will want to know the identity of the user so that it can serve customized content specific to that user. This base64 decoding can be done by a Web service such as a Java servlet running on your Web server.
For instance, our example iChainAuthHeader.java servlet will produce the output shown in Figure 4 for the user "cn=sjohns, o=novell" (password "novell").
The iChainAuthHeader.java servlet decodes the HTTP authorization header to discover the identity of the user making the request for Web services.
Here is a code snippet from the iChainAuthHeader.java servlet showing how it decodes the HTTP Authentication header:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import sun.misc.BASE64Decoder; String BASIC = "Basic ";" String encoded, decoded = null, username = null, password = null; String AuthHeader = (String) req.getHeader("Authorization");" // ***** Get the encoded username/password string // Example: Strip off "Basic " from "Basic c2pvaG5zLmNzaTo=bm92ZWxs"" encoded = AuthHeader.substring(BASIC.length()); BASE64Decoder decoder = new BASE64Decoder(); // ***** Decode the username/password string decoded = new String(decoder.decodeBuffer(encoded)); int index = decoded.indexOf(":");" if (index != -1) {! // ***** Separate "username:password"" username = decoded.substring(0, index); password = decoded.substring(index + 1); }
Note: For details on the Authorization section, see the HTTP 1.1 RFC document (RFC 2616), section 5.3 "Request Header Fields" and section 14.8 "Authorization" at http://www.faqs.org/rfcs/rfc2616.html.
Object-Level Access Control (OLAC) Parameter Extraction
For each authenticated user session, the user's userid is automatically extracted from NDS, injected into the Authorization section of the HTTP header, and passed on to the Web Server from the iChain proxy server as explained above.
But what if your Web Server needs additional NDS information besides just the userid? What if one of the additional Web servers that you are fronting with the iChain Proxy Server is providing Web services from an HR database such as PeopleSoft? In scenarios such as this, you may have the case where the NDS userid is not the unique key that the database needs to identify or access unique records.
Fortunately, there is an easy way to allow a third-party service such as PeopleSoft to take advantage of NDS and the iChain solution. The solution lies in creating a User object attribute in NDS that contains the necessary identification information.
For example, PeopleSoft might need a unique ID number to identify each user in the system. If you create an attribute in NDS called "EmployeeID" and populate each User object with the corresponding value for this attribute (see Figure 5), you can use the iChain feature called OLAC (Object-level Access Control) to pass other NDS data (other than the userid/CN) to your back-end Web services.
Populating NDS User objects with an "EmployeeID" attribute that can be passed to back-end Web services.
OLAC parameters make it possible to have other NDS data injected into the HTTP stream between the iChain Proxy Server and your Web Server (from the iChain Proxy Server to the Web Server). The OLAC parameters are configured via ConsoleOne on the ISO (iChain Service Object).
A typical OLAC configuration that will inject the NDS attributes of Surname, Given Name, and EmployeeID into the HTTP stream from the iChain Proxy Server to the Web Server is shown in Figure 6.
Configuring OLAC parameters in ConsoleOne.
The OLAC parameters are added to the QueryString that is passed from the iChain Proxy Server to the Web Server. These parameters are added to the QueryString in name=value format (for example, "LastName=Johns"). Multi- valued NDS attributes are also supported in the following format:
name=value1,value2,value3, . . .
An example of a multi-valued attribute is "Stocks=NOVL,DELL,CSCO,INTC".
In order for your Web Server to extract and parse these OLAC parameters in the QueryString, you need a service such as a Java servlet on your Web Server to do this. Figure 7 shows an example of what the output looks like from a servlet that extracts and parses OLAC parameters.
Sample output from OLAC parameter extraction servlet.
Below is the relevant code snippet from our sample iChainOLAC.java servlet:
import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; // ************************************************** out.println("[ Novell iChain 1.5: OLAC Servlet ]"br"");" out.println(""h2"QueryString:"/h2"");" out.println(" Query string: " + req.getQueryString());" // ************************************************** // ***** OLAC parameters out.println(""h2"OLAC parameters:"/h2"");" Enumeration e = req.getParameterNames(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); out.println(" " + name + " = " + req.getParameter(name));" }
Review of Previous Sections
Up to this point, we have discussed two Java servlets (iChainAuthHeader.java and iChainOLAC.java) that are running on your Web Server. These servlets are receiving and extracting NDS data without the Web Server/servlet developers having to know about or do any NDS programming.This is the power of iChain. With iChain, the NDS data is injected into the HTTP stream in standard locations (the AuthHeader and the QueryString) to make the data easily accessible to any Web application or service. All your Web developers need to do is extract data that is passed to them.
In the AuthHeader/userid scenario, the standard NDS attribute of CN (Common Name) is automatically injected into the Authorization section of the HTTP header for each authenticated user session. In iChain 1.5, you can configure the format of this userid to be provided in LDAP format (comma-delimited, fully distinguished, as in: "cn=sjohns,o=novell"). This AuthHeader injection occurs at the iChain Proxy Server and flows from the iChain Proxy Server to the Web Server.
In the OLAC scenario, the OLAC configuration is optional, not automatic like the AuthHeader functionality. In our example, the OLAC parameters of the NDS Surname, Given Name, and EmployeeID were configured on our ISO in ConsoleOne. Those NDS attributes were then extracted from NDS and injected into the QueryString sent from the iChain Proxy Server to the Web Server for each user session.
Here is an important thing to note about OLAC. To enhance performance, the OLAC parameters are read from NDS only when the user session is initially authenticated. These OLAC parameters are then cached by the iChain Proxy Server for the duration of that user session. When the user session ends due to user inactivity (session timeout) or user logout, the session is terminated and the OLAC parameters for that user session are no longer held in the cache. The next time the user authenticates and a new user session is built, the OLAC parameters will be read anew for the new user session.
During the life of the user session, the OLAC parameters are not reread or refreshed even if the values of those attributes are modified in NDS during the user session. Because of this, OLAC functionality should only be used for data that will not be changed during the life of a user session. For instance, our example "EmployeeID" attribute is a very static value that most likely would not change during the life of a user session. However, an attribute such as "Stocks" that contains stock ticker symbols for a user"s stock portfolio could likely change during the life of a user session (as the user modifies his or her stock portfolio). This type of attribute would not be a proper candidate for the OLAC functionality.
Advanced iChain Development
If your Web developers are familiar with NDS programming, or if your back-end Web services need to interact with NDS and iChain more intimately than can be done with the AuthHeader or OLAC features, you may want to look into more advanced NDS development options.
Two types of NDS operations that may be commonly used in iChain deployments are user self-registration services and user account modification services. Depending on what you want to do during each of these two processes, the development can become quite complex.
To illustrate these more advanced NDS operations. we'll look at an example Web environment that simulates a simplistic stock broker service that is fronted by the iChain infrastructure. Users will be able to register to this service as new users and enter their personal information and their stock portfolio information. After the user accounts are created, users can log in to our stock broker service (using the iChain authentication process) and modify their stock portfolios.
Because computer programming is more of an art than a science, different programmers like to use different tools and interfaces to address the same problem. NDS is well suited to provide this development flexibility. In our example stock broker service, we'll show how to implement this iChain environment using either the Novell Java Beans interface or the JNDI/LDAP interface, whichever your Web developers are more comfortable with.
User Self-Registration via Novell Beans
Novell Java Beans are a straightforward way to develop to NDS in Java servlets. The one drawback of using the Novell Java Beans is that the beans call down through to the native client libraries and so the Novell Java Beans require to be run on a server that has the NetWare Client installed. Currently this means that a servlet using the Novell Java Beans could only be run on a NetWare webserver or an NT/2000 webserver that has the NetWare Client installed.
The link to download the "Beans for Novell Services" and related documentation is http://developer.novell.com/ndk/bns.htm.
For our stock broker service example, we first want to provide a way for users to register if they haven't yet created an account with our service. To do this, we create an HTML registration form called 'iChainBeanRegisterForm.htm', shown in Figure 8.
HTML registration form for new users to create an account.
This form allows new users to enter their Username (userid), First Name, Last Name, Password, and their stock portfolio information (the ticker symbols of stocks they want to track, such as "NOVL"). Users can enter up to 10 stocks. Once the form is filled out and the user clicks the Submit button, this HTML form calls our iChainBeanRegister servlet as follows:
<form action="/servlet/iChainBeanRegister" method="POST" name="theForm"<
The iChainBeanRegister.java servlet, running on our Web Server, contacts our NDS Authorization Server where the directory is stored and creates the new user, via the Novell Beans, with the corresponding account and stock portfolio information. As shown in Figure 9, the stock portfolio information is stored in an attribute called "Stocks."
In our example, the user's stock portfolio information is stored in an NDS User object attribute named 'Stocks.'
The registration success is communicated to the user via a screen generated by the servlet, shown in Figure 10.
Confirmation page that appears after a user has successfully registered.
The abbreviated code snippet from the iChainBeanRegister.java servlet that performs this add function is shown below:
import com.novell.beans.NWDir.*; import com.novell.beans.NWSess.*; import com.novell.beans.util.*; ... NWDir dirBean = null; NWEntry parent = null; Entries children = null; ... // ***** instantiate NWDir Novell Bean dirBean = (NWDir)java.beans.Beans.instantiate(getClass().getClassLoader(), "com.novell.beans.NWDir.NWDir");" // ***** Set NWDir bean to our NDS context dirBean.setFullName(NDScontext); // ***** Get New User ID from the Form String strUid = req.getParameter("uid");" if ((strUid != null) !!) != 0)) {! // ***** ADD USER AddUser(dirBean, NDScontext + "\\", strUid, req, resp, out);" } ... // ***** AddUser() public void AddUser(NWDir dirBean, String cx, String uid, HttpServletRequest req, HttpServletResponse resp, PrintWriter out) throws ServletException, IOException { NWEntry parent = dirBean.getEntry(); NWEntry nwEntry = dirBean.createEntry("User", uid);" NWEntries children = parent.getEntries("User");" // ***** Add MANDATORY attribute (Surname) nwEntry.setFieldValue("Surname", strLN);" // ***** Add OPTIONAL attributes nwEntry.setFieldValue("Given Name", strFN);" // ***** Add OPTIONAL attributes: Stock portfolio...up to 10 stocks stk1 = req.getParameter("Stock1");" if ((stk1 != null) !!) != 0))! nwEntry.setFieldValue(StocksNDSattr, stk1); stk2 = req.getParameter("Stock2");" if ((stk2 != null) !!) != 0))! nwEntry.setFieldValue(StocksNDSattr, stk2); ... // ***** Perform the add (throws NWBeanException if add fails) children.addElement(nwEntry); out.println(""br"SUCCESS: User added successfully""br"");" } // END of AddUser()
User Account Modification via Novell Beans
Once a user is added to the directory, the user can modify his or her stock portfolio information by accessing the iChainBeanModify.java servlet by clicking on a link similar to this:
http://sjohns6.provo.novell.com/servlet/iChainBeanModify
Since we've configured iChain to protect this servlet and treat it as a private resource, iChain will require any user that attempts to access this servlet to be authenticated. When the newly-registered user first requests this servlet, the user will be presented with the iChain login page to authenticate. Once authenticated, the user can modify the stock portfolio (for example, replace 'DELL' with 'CPQ'). After the modification is made, the user will be presented with the confirmation page shown in Figure 11.
Confirmation page that appears after a user has modified stock portfolio information in the Novell Beans example.
The iChainBeanModify.java servlet, which is running on our Web Server that is fronted by the iChain Proxy Server, only receives the user session once the user has been successfully authenticated via the NDS authorization server. When the iChainBeanModify.java servlet is accessed, the servlet must extract and decode the userid from the Authorization section of the HTTP header that it receives from the iChain Proxy Server.
The following code snippet from iChainBeanModify.java shows how the Web Server is taking advantage of the iChain user identity management technology:
// ***** Get UserID from the encoded http header section "Authorization"" String strUid = GetUID(req); out.println("User ID: "" + strUid + """br"");" ... // ***** Get the encoded Authorization header public String GetUID(HttpServletRequest req) { String BASIC = "Basic ";" String encoded, decoded, username = null, password = null; String AuthHeader = (String) req.getHeader("Authorization");" int index = AuthHeader.indexOf(BASIC); // ***** Get the encoded username/password string encoded = AuthHeader.substring(BASIC.length()); BASE64Decoder decoder = new BASE64Decoder(); // ***** Decode the username/password string decoded = new String(decoder.decodeBuffer(encoded)); index = decoded.indexOf(":");" if (index != -1) {! // ***** Separate into username and password username = decoded.substring(0, index); password = decoded.substring(index + 1); } return username; } // END of GetUID()
User Self-Registration via JNDI/LDAP
We can create the same functionality in our example stock broker service environment by using the JNDI/LDAP interfaces rather than Novell Java Beans. This would be a good choice if your Web developers are more familiar with JNDI/LDAP, or if your Web Server that will be a part of the iChain environment cannot run the Novell Client. One advantage of using the JNDI/LDAP interfaces to develop to NDS is that the Web Server running the servlets that are using JNDI/LDAP does not have to have the Novell Client installed. The JNDI/LDAP interfaces do not call down through the native Novell Client methods.
The link to download the "LDAP Service Provider for JNDI" and related documentation is http://developer.novell.com/ndk/ldapjndi.htm.
The steps to implement the user self-registration service via JNDI/LDAP start off by creating an HTML form similar to the one used with the Novell Java Beans. However, this JNDI/LDAP form calls our iChainLDAPRegister.java servlet as follows:
<form action="/servlet/iChainLDAPRegister" method="POST" name="theForm"<
Here is the code snippet from the iChainLDAPRegister.java servlet that performs the addition of the new user and creation of the stock portfolio.
import java.util.Enumeration; import java.util.Hashtable; import javax.naming.*; import javax.naming.directory.*; ... Attributes attrs = new BasicAttributes(); attrs.put( "objectClass", "inetOrgPerson" );" // ***** Add MANDATORY attribute Surname (LastName) attrs.put( "surname", strLN );" // ***** Add OPTIONAL attribute GivenName (FirstName) attrs.put( "givenName", strFN );" // ***** Add OPTIONAL attributes: Stock portfolio...up to 10 stocks Attribute stks = new BasicAttribute(StocksNDSattr); stk1 = req.getParameter("Stock1");" if ((stk1 != null) !!) != 0))! stks.add( stk1 ); stk2 = req.getParameter("Stock2");" if ((stk2 != null) !!) != 0))! stks.add( stk2 ); ... // ***** Stuff Stocks in "attrs" object" attrs.put( stks ); // ***** Perform the add ldapContext.createSubcontext( uid, attrs );
User Account Modification via JNDI/LDAP
In our example stock broker service, once new users have registered themselves via JNDI/LDAP, they can modify their stock portfolio information by accessing the iChainLDAPModify.java servlet. This servlet is set up in iChain to be a private resource which requires user authentication via the directory before this servlet can be accessed.
When a newly-registered user attempts to access this servlet, he or she will receive the iChain login page to authenticate. Once successfully authenticated, let's say the user modifies the stock portfolio information by replacing 'CPQ' with 'AAPL'. Once this modification is made, the user will see a confirmation screen generated by the iChainLDAPModify.java servlet (see Figure 12).
Confirmation screen that appears after a user has modified stock portfolio information in the JNDI/LDAP example.
Conclusion
Novell iChain 1.5 is a powerful, directory-based infrastructure that is designed to support any type of Web server and to easily integrate with your existing Web services environment. The iChain features of AuthHeader and OLAC allow your Web developers to take advantage of NDS without doing any NDS development. OLAC is designed to provide a cached "snapshot" of NDS attributes at the time of user login. This snapshot is cached by the iChain Proxy Server and is not refreshed or reread until the user session is terminated and established again.
The iChain/NDS foundation is a flexible development platform that supports multiple interfaces and allows developers to choose the development interface that they are most comfortable with, such as Java Beans or JNDI/LDAP.
* Originally published in Novell AppNotes
Disclaimer
The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.