C HTTP Listener's Web Gateway Service

Oracle Virtual Directory's HTTP Listener provides an HTML-based gateway, known as the Web Gateway, that provides DSML and XSLT-rendered directory reporting. The Web Gateway's DSML functionality is based on Oracle's URL-based query gateway that returns DSML formatted XML results based on URL based operations. A DSMLv2 service is offered separately through the HTTP Listener's DSML V2 Service.

This appendix describes the HTTP Listener's Web Gateway and contains the following sections:

C.1 Web Gateway Functionality and Features

In addition to providing DSML and XSLT-rendered directory reporting, the Web Gateway also provides the ability to serve static web content, allowing you to construct sophisticated directory white pages, delegated administration, and self-service functions.

The following is a list of Web Gateway features:

  • dynamic integration with the Oracle Virtual Directory directory service.

  • Apache-like security with LDAP integration providing authentication and authorization.

  • dynamic XSLT translation providing output rendered in XHTML, DSML, WML, or any XML derivative form.

  • support for static content, for example, typical HTML files.

  • extended support for form-based input supporting all LDAP operations, including add, modify, and delete.

  • extended support for retrieving binary attributes such as jpegphoto or usercertificates.

  • integrated support of Oracle Virtual Directory's denial of service protection mechanism.

C.2 Demonstration Directory Browser

Oracle Virtual Directory includes a demonstration directory browser in the htdocs directory that highlights the capabilities of the XSLT Listener's XML services. This demonstration directory browser is not designed to be a sophisticated tool for production purposes, but is provided as example code that developers may review and extend for their specific purposes.

Note:

Oracle does not provide coding level support for Oracle Virtual Directory. However, Oracle can provide assistance through its consulting services programs to provide development assistance.

C.3 Web Gateway Architecture

The Web Gateway is based on the Jetty server used in the popular open source Apache AXIS and Tomcat servers. The Jetty server is an extensible server designed for embedding into special purpose products. The following is a description of the components in the Web Gateway architecture, including:

C.3.1 DSML Serverlet

The DSML serverlet receives request and calls Oracle Virtual Directory's internal API so that the request is treated as if it came from the Listener. The directory can be queried for standard DSML content by using the /dsml prefix with an appropriate query, for example:

http://localhost:8080/dsml/directory?base=o=myorg.com&scope=base&filter=objectclass=*

When the URL is received by the Listener, the query is processed in the context of the HTTP session. If no user security principal is present, the query is treated as an anonymous query. After the query is processed, results are returned to the HTTP client in DSML standard form.

Security context can be established by replacing "directory" with a server directory context. A security context for DSML can be established by creating an .htaccess file in an appropriate subdirectory of htdocs. For example, to set a restrictive query domain, place a .htaccess file in the /htdocs/dsml/administrators directory, causing queries to http://localhost:8080/dsml/administrators to meet the access requirements specified in the /htdocs/dsml/administrators/.htaccessaccess file.

C.3.2 XSLT Serverlet

The XSLT serverlet enables you to control how the HTML appears. The servlet provides the ability to query the directory for content and to have it translated according to a specified XSLT translation file.

The XSLT servlet supports both directory queries and specialized commands to support specialized processing. For example:

http://localhost:8080/search/results.xsl?params=...

The .xsl file suffix indicates the XSLT servlet and /search/results.xsl specifies the XSL translation file used to render the results and /search/results.xsl is automatically mapped to /htdocs/search/results.xsl.

C.3.3 Handlers

  • DoS Handler: Every request is tracked by subject name and IP address against overall DoS Manager quotas (as defined in vde.prop). During a quota exceeded event, the server becomes unresponsive to the offending client, which protects the web service if you have an over-active client or denial of service attack.

  • LDAPUserRealm: The LDAPUserRealm works with the HTAccessHandler and integrates the Web Gateway with the directory service, that is, Oracle Virtual Directory. The LDAPUserRealm performs user authentication against the directory and tracks user context for other operations, including providing uid to distinguished name mapping.

  • HTAccessHandler: This handler provides Apache-like web server access control by examining each resource requested and looking for an .htaccess file in the resources directory or parent directory. If a .htaccess file is not found, the default access control specified in /conf/htaccess.prop is used. If the current user context is not authorized to see the current resource, HTAccessHandler returns an access denied response to the HTTP client. When the browser responds with a user-id and password, the LDAPUserRealm service automatically creates an LDAP User Principal, which can be referenced by the HTAccessHandler for authorization purposes.

    Refer to "Security Contexts" for more information.

  • Servlet Handler: The servlet handler directs URL requests ending in .xsl to the Web Gateway servlet and URL requests beginning with /dsml to the DSML servlet. The Web Gateway servlet provides XSLT formatted results and support both directory query and entry modification operations. The DSML servlet provides simple directory query and DSML formatted response functions.

  • Resource Handler: All other requests are treated as document resource requests. If the resource is located in the htdocs document root of the server, the document is returned to the HTTP client. Static content, for example, html and gif files, may be served from the Web Gateway through the Resource Handler just as on a standard web server. Access control on static content is enforced according to the presence of a .htaccess security configuration file in the document directory or parent directory. Static documents found in the htdocs directory of the Oracle Virtual Directory installation are mapped directly to the main server root. For example, /htdocs/index.html maps to http://localhost:8080/index.html.

C.4 DSML and XSLT LDAP Query Parameters

The WebGateway supports the following DSML and XSLT LDAP query parameters:

base=[dn]

The base distinguished name where the search begins. If empty, null is assumed.

filter=[searchfilter] ]

An LDAP standard search filter. If empty, "(objectclass=*)" is assumed.

scope=[base|onelevel|sub] ]

The scope of the search. Base specifies that only the entry specified in the base is searched (useful for directly addressing an entry). onelevel specifies that searches look only at the immediate child entries below the base dn. Subtree specifies that all descendants of the basedn are to be searched. By default, scope is set to base.

binddn=[userDN]

The user distinguished name the search is to execute under. If empty, the default assumed is anonymous.

password=[password]

The password associated with the binddn account. This parameter is normally specified with a binddn.

xsl=[xsl-file] (Deprecated)

This parameter applies only to the XSLT serverlet and is ignored by the DSML serverlet. When specified, the parameter references a file relative to the root installation directory of Oracle Virtual Directory. HTML files are relative to the htdocs directory). If empty, the default value is conf/html.xsl

[any]=[value]

The XSLT serverlet accepts any additional parameters you want to provide, which is useful if you want to pass a parameter to an XSL style sheet to provide contextual information, for example, parentname="Home".

C.5 Web Gateway Commands

Web Gateway commands provide additional features such as binary attribute retrieval, form-based searching, and form-based entry manipulation. The following is a description of the each of the Web Gateway commands, including:

C.5.1 Binary Attribute Retrieval Commands

The getcert and getphoto commands are used to retrieve binary attributes in their native binary forms, as opposed to encoded in DSML. A call to getcert returns http content with mime type application/x-x509-email-cert. Similarly, a call to getphoto returns content with mime type image/jpeg.

cmd=getcert

Retrieves a certificate specified by the dn and attr parameters. For example:

http://localhost:8080/xslt/search/?cmd=getcert&dn=uid=jsmith,ou=people,o=airius.com&attr=usercertificate
cmd=getphoto

Retrieves a jpegphoto as specified by the dn and attr parameters.

dn=[distinguished name]

Specifies the distinguished name of an entry. Typically used with a command parameter.

attr=[attribute name]

Specifies the name of an attribute in relation to a getcert or getphoto command.

C.5.2 Form-Based Searching Commands

While it is possible to do an LDAP-like XSLT/DSML style search, the cmd=search option allows more flexibility for supporting user-friendly search forms. This command takes form values and converts the content into a standard directory query.

cmd=search

Provides support for a form-based search with related parameters: base, scope, kind, searchvalue, and filterattrs. This command provides similar functionality to the XSLT query form except that it is designed to make it easier to program search forms where the search filter is automatically constructed from the form parameters. Example:

http://localhost:8080/xslt/search/results.xsl?cmd=search&base=o=airius.com&scope=sub&kind=all&filterattrs=cn,sn,givenname&searchvalue=smith
base=[distinguished name]

Specifies the search base for a form-based search command.

scope=[base|one|sub]

Specifies the scope of the search. Valid values are base, one, and sub.

kind=[all|attrname]

Specifies whether the search filter is constructed based on a specific attribute or based on all attributes specified by the filterattrs parameter

filterattrs=[attr1,attr2,…]

The list of attributes to search against.

searchvalue=[user searchstring value]

The value entered by the user as the searchstring value.

The action of a search form can be constructed as a GET or a POST. The following is an example of a GET request generated by a search form:

http://localhost:8080/xslt/search/results.xsl?cmd=search&base=o=airius.com&scope=sub&kind=all&filterattrs=cn,sn,givenname&searchvalue=smith

This command would be interpreted by the server and processed as equivalent to:

http://localhost:8080/xslt/search/results.xsl?base=o=airius.com&scope=sub&filter=(|(cn=*smith*)(sn=*smith*)(givename=*smith*))

After processing the query, the results would be translated using the XSL file /xslt/search/results.xsl.

C.5.3 Form-Based Entry Manipulation Commands

The modify command allows for construction of html forms that you can use to modify directory entries. The commands provide the ability to add, delete, or modify virtually any LDAP directory entry.

Some form parameters can be provided as hidden fields, for example, attrs, changetype, and objectclass. When adding new entries, remember to supply the objectclass attribute, which is usually supplied as a hidden field.

Note:

The term attrx in the following descriptions represents any valid LDAP attribute.

cmd=modify

Indicates the client has requested modification of a directory entry. The type of modification is specified in the changetype field.

changetype=[add|modify|delete]

Specifies the operation on the directory entry to be performed: add, modify, or delete. Only one directory entry can be modified in any operation.

When adding a new entry using changetype=add only the attrx_modify=[value] values is processed. When deleting an entry, all attrx parameters are ignored. You can delete multiple LDAP entries by providing multiple dn form values.

dn=[distinguished name]

The distinguished name of the entry to be added, modified, or deleted.

modify_attrs=[attr1,attr2,attr3]

The list of attributes to be processed from the form. This list is used to locate all other attribute parameters on the form, for example, attr1_type, attr1_action, attr1_new, attr1_confirm.

xslerror=[/dir/error.xsl]

Specifies an xsl file to direct errors to if a processing error occurs. If an error occurs, the XSL form passes all form parameters provided, and the result and message parameters. These can be parsed in error.xsl to determine the appropriate error message to display to the end user.

attrx_type=[single|multi|photo|cert]

Defines the type of attribute represented by attrx. If it is single, only the first value of attrx is accepted. If it is cert or photo, the binary value is located as part of a multi-part form. One value can be added at a time.

attrx_required=[true|false]

If set to true, the processor verifies a value is present for attrx.

attrx_delete=[value]

A value to be deleted from attrx. One or more values can be specified. An empty value is ignored.

attrx_modify=[value]

The value used to modify the attrx attribute. Depending on the value of attrx_action, this value is added to attrx or replaces all values in attrx.

attrx_action=[add|replace]

Specifies whether the value in attrx_modify is added to attrx or replaces all existing values. When changetype=add, attrx_action is forced to be add.

rdn_attr=[attr]

During an add operation, dn is assumed to be the parent entry, and rdn_attr informs the processor which attribute to use for the rdn value.

C.5.4 HTTP POST

You can use HTTP POST interchangeably with HTTP GET. There is a maximum input file size in the Listeners.prop file that can be set to prevent denial of service or buffer overflow attacks. Use multi-part forms according to RFC 1867 when binary attributes, for example jpegphotos and certificates, are to be uploaded.

C.5.5 HTTP GET

When using HTTP GET operations, all parameters are passed as a URL, allowing you to bookmark the URLs. However, confidential information, such as the binddn, is available in the URL, so you may want to use HTTP POST for non-anonymous queries.

You must use escape ampersands (&) and spaces appropriately to conform with URL requirements when using GET. This may require the addition of javascript to modify field parameters before submission. In general, ampersands (&) must be replaced with &.

C.6 Security Contexts

The HTAccessHandler enables you to define security contexts within the server. A Security Context defines which IP addresses, subjects, or groups may access a particular resource directory on the server. You can create security contexts by creating a .htaccess security configuration file in the htdocs directory or any subdirectory. Each .htaccess file applies to directory it resides in and any child directories below it. The .htaccess file in the immediate directory or closest parent is the file applied to any resource. You can define a default security context by editing the /conf/htaccess.prop file.

The following information provides more detail on security contexts, including:

C.6.1 Requirements for .htaccess Files

The following is a list of requirements for .htaccess files:

  • The .htaccess file must be a plain text file.

  • Any content that is not a valid directive must be prefixed with a comment (#) character.

  • Directives in a .htaccess file apply to the current or child directories only.

  • If a sub or child directory contains a .htaccess file, it overrides the .htaccess files of its parent directories.

C.6.2 Directives for .htaccess Files

The following is a list of supported .htaccess file directives:

AuthUserFile [filename]

Indicates users are authenticated using a text file that contains a list of users and passwords encrypted with the CRYPT hash. Refer to Example C-2 to see an example.

AuthUserLDAP [base]

Indicates users are authenticated from the Oracle Virtual Directory server. base specifies the distinguished name of the search base for authenticated users.

AuthGroupFile [filename]

Indicates users must be a member of the group file specified by filename. Refer to Example C-3 for an example.

AuthName [name]

Sets the name of the authentication realm. This is the text displayed in the challenge to the user, that is, in the Directory Browser.

<Limit>

[restrictions]

Refer to "Resource Restrictions" for more information.

</Limit>

Defines a resource restrictions block. Restrictions are placed within the tokens <Limit> and </Limit>.

C.6.3 Resource Restrictions

Resource restrictions are placed between <Limit> statements. The following is a list of the supported restrictions:

satisfy [all|any]

Specifies where all or any requirements must be satisfied.

require [user|valid-user|group|ldapgroup] [entities]

Specifies that the user must be a member of one of the following:

  • user: Either a member of AuthUserFile or AuthUserLDAP

  • valid-user: Any validated user

  • group: A member of AuthUserGroup

  • ldapgroup: A member of an LDAP group

entities specifies either an ldapgroup enclosed in round brackets(), or an explicit list of user names or groups.

order [allow,deny|deny,allow|mutual-failure]

Specifies rule precedence for allow and deny rules as follows:

  • allow,deny: Must be on the allow list and cannot be on the deny list.

  • deny,allow or mutual-failure: Allow if not on the deny list or allow if on the allow list.

allow from [ip address list]

Specifies a space-separated list of IP addresses to allow requests from.

deny from [ip address list]

Specifies a space-separated list of IP addresses to deny requests from.

C.6.4 Example Security Context Files

The following are example security context files. Example C-1 demonstrates an example .htaccess file:

Example C-1 Example .htaccess file

# HTAccess example.
#
AuthName "Airius Directory Browser"
AuthType Basic
#AuthUserFile /etc/htpasswd
AuthUserLDAP ou=People,o=Airius.com
AuthGroupFile /etc/htgroup
<Limit>
satisfy any
require ldapgroup (cn=a group,ou=groups,o=Airius.com)
require ldapgroup (cn=alternate group,ou=groups,o=Airius.com)
order deny,allow
deny from 192.168.0.3 192.168.0.4
</Limit>

Example C-2 demonstrates an example htpasswd file:

Example C-2 Example htpasswd file

# <PRE>
# HTPassword example.
#
# Passwords must be in CRYPT format
#
admin: adpexzg3FUZAk
tom: tofn8Rh1L.xhQ
dick: diF1tp4K2rvw.
harry: haVyKPUXAHTjA

Example C-3 demonstrates an example htgroup file:

Example C-3 Example htgroup file

# HT Group example.
# Place uid values after group name
#
Users: tom dick harry jturner
TestGroup: tom harry
AdminGroup: admin

C.7 Using XSL Stylesheets

The following information describes techniques for using XSL stylesheets, including:

C.7.1 Using XSLT Serverlet Queries to Create Dynamic Groups

You can use an XSLT query combined with a stylesheet to create an edit form for a client, for example:

http://localhost:8080/manage/edit.xsl?base=ou=Atlanta,o=myorg.com&scope=base&filter=objectclass=*&mode=edit

This URL causes the server to retrieve the directory entry ou=Atlanta,o=myorg.com and pass it to the /manage/edit.xsl xsl form.

Inside the xsl form, look for the mode parameter to determine how to render the result. In this case, edit might mean that the form should be rendered so that the object returned by the query can be edited. The addchild mode might be used to prepare a form that could be used to add a child entry to the organization.

You can create a new mode parameter. For XSL, mode is a special parameter often used in templates to cause different logic to occur for different rendering subroutines. In the default shipping demonstration application, htdocs/xslt/secure/admin.xsl provides multi-mode editing (that is, display, add, modify, delete) within a single style sheet.

C.7.2 Setting Content-Type Serverlet Based on Media Type Attribute

When using an XSLT stylesheet to process data into HTML, the Oracle Virtual Directory Web Gateway examines the xsl:output tag for a media-type attribute. If one is present, the Web Gateway sets the content-type serverlet to the same setting as the media-type attribute. If a media-type attribute does not exist in the xsl:output tag, the content-type serverlet uses text/html by default.

C.7.3 Support for XSL Document() and Import/Include Commands

The XSLT servlet processor in Oracle Virtual Directory supports the document() command. You can specify either a complete document URL or a file specification. If you specify just a directory or document, it is treated as relative to the htdocs document root location.

For example, the vdexsl.xml file is used to translate LDAP attribute names into more readable names:

<xsl:variable name="lname" 
select="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
<xsl:variable name="prettyname" 
select="document('xslt/vdexsl.xml')/vdexsl:vdexsl/vdexsl:fields/vdexsl:attr[@name=$lname]/vdexsl:
displayname"/>

Files retrieved using the document() command are automatically cached for performance reasons. Similarly, the xsl:import and xsl:include commands are also supported and used to import global subroutines into your XSL templates. As with the document() command, references can be to any URL or file. By default, file references are relative to the htdocs document root location. The following are two examples:

<xsl:import href="http://192.168.0.2:8050/lib/globals.xslt"/>
<xsl:import href="lib/globals.xslt"/>

Note:

If you are using HTTP to retrieve a stylesheet from an Oracle Virtual Directory, using the .xsl file suffix causes the XSLT servlet to intervene and render the xsl file as if it were part of a query. To retrieve an unprocessed XSL file from another Oracle Virtual Directory, it must have a suffix name other than .xsl. In the example above, the .xslt directory is used instead.

C.7.4 Passing Parameters to XSL Stylesheets

The XSLT servlet makes all parameters that are passed to it available to the XSL style sheet. This allows XSL stylesheets to receive contextual information that may not be present in the DSML search results. Parameters can be part of the valid search parameters or other parameters defined for this purpose. In the following example code, the parentname and base parameters are retrieved and made available as variables within the XSL code:

…
<xml:output method="html" indent="yes"/>
<xsl:param name="parentname" select="'Root'"/>
<xsl:param name="base" select="'base'"/>
<xsl:template match="/">
<html>
…

The select part of the xsl:param statement represents the default value if it is not present.

C.7.5 Example XSL

The following Example C-4 is designed to build a directory navigation bar. You can consult any guide on XSLT for more information on XSL programming. Example C-4 pulls in two parameters to establish context. The parentname and base parameters are used to remember the parent entries name so that navigation up the tree and down the tree is possible. The parent's parent DN is assumed by dropping the RDN from the current base query parameter.

Example C-4 Example XSL

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/REC-html40"
xmlns:dsml="http://www.dsml.org/DSML">
<xml:output method="html" indent="yes"/>
<xsl:param name="parentname" select="'parentname'"/>
<xsl:param name="base" select="'base'"/>
<xsl:template match="/">
<html>
<head>
<title>Oracle Browser Navigation Bar</title>
</head>
<body bgcolor="#99CCCC">
<xsl:choose>
<xsl:when test="$base = 'base'">
<xsl:variable name="rdn" select="'root'"/>
<xsl:variable name="rvalue" select="'Root'"/>
<xsl:variable name="parentdn" select="'base=&amp;scope=base'"/>
<FONT FACE="Verdana,Arial" size="-1">Root</FONT>
</xsl:when>
<xsl:when test="$base = ''">
<xsl:variable name="rdn" select="'root'"/>
<xsl:variable name="rvalue" select="'Root'"/>
<xsl:variable name="parentdn" select="'base=&amp;scope=base'"/>
<FONT FACE="Verdana,Arial" size="-1">Root</FONT>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="rdn">
<xsl:choose>
<xsl:when test="contains($base,',') = 'true'">
<xsl:value-of select="substring-before($base,',')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$base"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rvalue" select="substring-after($rdn,'=')"/>
<xsl:variable name="parentdn">
<xsl:choose>
<xsl:when test="contains($base,',') = 'true'">base=<xsl:value-of select="substring-after($base,',')"/>&amp;scope=onelevel</xsl:when>
<xsl:otherwise>base=&amp;scope=base</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<a href="/xslt?{$parentdn}&amp;filter=(objectclass=*)&amp;parentname={$parentdn}&amp;xsl=htdocs/Browser-navbar.xsl" target="leftFrame">
<FONT FACE="Verdana,Arial" size="-1"><xsl:value-of select="$rvalue"/></FONT></a>
</xsl:otherwise>
</xsl:choose>
<table border="0" cellpadding="0" cellspacing="0">
<xsl:apply-templates select="dsml:dsml/dsml:directory-entries/dsml:entry"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="dsml:entry">
<xsl:variable name="edn" select="@dn"/>
<xsl:variable name="evalue">
<xsl:choose>
<xsl:when test="contains(@dn,',') = 'true'">
<xsl:value-of select="substring-after(substring-before(@dn,','),'=')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-after(@dn,'=')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="@dn = ''">
<xsl:for-each select="dsml:attr[@name='namingContexts']/dsml:value">
<tr><td><li><a
href="/xslt?base={.}&amp;scope=onelevel&amp;filter=(objectclass=*)&amp;parentname
={.}&amp;xsl=htdocs/Browser-navbar.xsl" target="leftFrame"><FONT
FACE="Verdana,Arial" size="-1"><xsl:value-of select="."/></FONT></a>
<FONT FACE="Verdana,Arial" size="-1">[<a
href="/xslt?base={.}&amp;scope=base&amp;filter=(objectclass=*)&amp;xsl=htdocs/res
ults.xsl" target="mainFrame">-></a>]</FONT></li>
</td></tr>
</xsl:for-each>
</xsl:if>
<xsl:if test="@dn > ''">
<tr><td><li><a href="/xslt?base={@dn}&amp;scope=onelevel&amp;filter=(objectclass=*)&amp;parentna
me={$evalue}&amp;xsl=htdocs/Browser-navbar.xsl" target="leftFrame"><FONT
FACE="Verdana,Arial" size="-1"><xsl:value-of select="$evalue"/></FONT></a>
<FONT FACE="Verdana,Arial" size="-1">[<a
href="/xslt?base={@dn}&amp;scope=base&amp;filter=(objectclass=*)&amp;xsl=htdocs/r
esults.xsl" target="mainFrame">-></a>]</FONT></li>
</td></tr>
</xsl:if>
</xsl:template>