Commit 4e2f884a authored by Marc Boorshtein's avatar Marc Boorshtein

ITS 3771 - Added SPML Connection Siupport

Added better compilation support and updated the readme
parent 3376f562
LDAP Classes for Java
October 2003
June 2005
Table of Contents
1.0 LDAP Classes for Java
2.0 Known Issues and Solutions
3.0 Dependencies
4.0 Installation
5.0 LDAPv2 and LDAPv3 Support
6.0 Java LDAP Documentation
7.0 Building JLDAP
8.0 Building DSML Services
8.1 dsmlstream.war
8.2 dsmldom.war
1.0 LDAP Classes for Java
2.0 Known Issues and Solutions
3.0 Dependencies
4.0 Installation
5.0 LDAPv2 and LDAPv3 Support
6.0 Java LDAP Documentation
7.0 Building JLDAP
8.0 Building DSML Services
8.1 dsmlstream.war
8.2 dsmldom.war
9.0 Building DSMLv2 & SPML Connection Support
10.0 Using DSMLv2 Connection Support
11.0 Using SPML Connection Support
1.0 LDAP Classes for Java
......@@ -322,6 +325,75 @@ and dsmldom.war. See README.dsml for additional information.
ant wars
9.0 Building DSMLv2 & SPML Connection Support
The JLDAP libraries provide optional support for using DSMLv2 and SPML in
a similar fashion as you would use an LDAP connection. In order to build
support for this functionality into JLDAP you need to add the following
libraries to the "ext" directory of your JLDAP source directory:
commons-httpclient-*.jar - http://jakarta.apache.org/site/news/news-2005-q2.html#20050410.1
openspml.jar & soap.jar - http://www.openspml.org/
10. Using DSMLv2 Connection Support
The JLDAP libraries provide optional support for interacting with DSMLv2 based directories
like you would an LDAP directory. In order to use this functionality, you first create your
DSML connection:
DsmlConnection dsmlCon = new DsmlConnection();
//Some DSMLv2 implementations do not support SOAP
dsmlCon.setUseSOAP(true);
//The port is in the URL
dsmlCon.connect("http://my.ldap.domain.com:port/path/to/dsmlv2",0);
LDAPConnection con = dsmlCon;
con.bin("CN=User","secret");
.
.
.
Once case to an LDAPConnection, you can perform any synchronouse operation. Operations that
involve queue's are not supported. The bind operation includes the bind dn and password in
an HTTP BASIC authentication header.
In addtion you may create an implementation of the com.novell.ldap.util.HttpRequestCallback
interface to add HTTP Header variables.
The DSMLv2 connection library has been tested with Novell DSMLv2 web services, Octet String
VDE 3.0+ and IBM Tivoli Directory Integrator.
11. Using SPML Connection Support
The JLDAP libraries provide optional support for the Service Provisioning Markup Language.
SPML is a standard for integrating and interacting with provisioning servers. SPML support
is provided by the OpenSPML project. In order to use SPML using JLDAP:
//Create the connection using a "no auth" implementation.
SPMLConnection spmlCon = new SPMLConnection("com.novell.ldap.spml.NoAuthImpl");
spmlCon.connect("http://my.spml.domain.com/path/to/spml",0);
LDAPConnection con = spmlCon;
.
.
.
Like the DSMLv2 connection libraries, the SPML libraries only support synchronous operations.
As in DSMLv2, there is no BIND operation. Each SPML implementation has it's own standard. JLDAP
contains support for Sun Identity Manager and OpenSPML implementations. New authentication
schemes can be implemented by implementing the com.novell.ldap.spml.SPMLImpl interface.
When manipluating users, the DN takes the follwing form:
IdentityType=name
For instance, using the GenericString identifier the DN may be
GenericString=myUserName
$OpenLDAP$
******************************************************************************
* Copyright (C) 1999 - 2003 Novell, Inc. All Rights Reserved.
......
......@@ -40,6 +40,7 @@
<property name="docsrc" value="."/>
<property name="src" value="."/>
<property name="ext" value="ext"/>
<property name="ldap" value="ldap"/>
<property name="lib" value="lib"/>
......@@ -64,6 +65,32 @@
<!-- =================================================================== -->
<target name="init">
<tstamp/>
<mkdir dir="ext"/>
<condition property="exclude.dsmlconnection" value="com/novell/ldap/Dsml*.java,com/novell/ldap/DSML*.java,com/novell/ldap/util/HttpRequestCallback.java">
<not>
<available classname="org.apache.commons.httpclient.methods.PostMethod" >
<classpath>
<fileset dir="${ext}">
<include name="commons-httpclient-*.jar"/>
</fileset>
</classpath>
</available>
</not>
</condition>
<condition property="exclude.spmlconnection" value="com/novell/ldap/spml/*.java,com/novell/ldap/SPML*.java">
<not>
<available classname="org.openspml.client.SpmlClient">
<classpath>
<fileset dir="${ext}">
<include name="openspml*.jar"/>
</fileset>
</classpath>
</available>
</not>
</condition>
<echo message="dsmlv2 connnection is available : ${exclude.dsmlconnection}"></echo>
<echo message="spml connnection is available : ${exclude.spmlconnection}"></echo>
</target>
<!-- =================================================================== -->
......
......@@ -66,7 +66,7 @@ public class DsmlConnection extends LDAPConnection {
/** determine if we are "connected" */
boolean isConnected;
boolean useSoap;
/** The host extracted from the url */
private String host;
......@@ -108,7 +108,9 @@ public class DsmlConnection extends LDAPConnection {
//First load up the content headers
post.setRequestHeader("Content-Type","text/xml; charset=utf8");
post.setRequestHeader("SOAPAction","#batchRequest");
if (this.useSoap) {
post.setRequestHeader("SOAPAction","#batchRequest");
}
......@@ -128,17 +130,20 @@ public class DsmlConnection extends LDAPConnection {
//First print the SOAP Envelope
pout.println("<?xml version=\"1.0\" encoding=\"UTF8\"?>");
pout.println("<soap-env:Envelope xmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\">");
pout.println("<soap-env:Body>");
if (this.useSoap) {
pout.println("<soap-env:Envelope xmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\">");
pout.println("<soap-env:Body>");
}
//write out the message
writer.writeMessage(message);
writer.finish();
//Complete the SOAP Envelope
pout.println("</soap-env:Body>");
pout.println("</soap-env:Envelope>");
if (this.useSoap) {
//Complete the SOAP Envelope
pout.println("</soap-env:Body>");
pout.println("</soap-env:Envelope>");
}
ByteArrayInputStream in = new ByteArrayInputStream(out.toString().getBytes("UTF-8"));
......@@ -197,8 +202,9 @@ public class DsmlConnection extends LDAPConnection {
//First load up the content headers
post.setRequestHeader("Content-Type","text/xml; charset=utf8");
post.setRequestHeader("SOAPAction","#batchRequest");
if (this.useSoap) {
post.setRequestHeader("SOAPAction","#batchRequest");
}
if (this.callback != null) {
......@@ -215,18 +221,20 @@ public class DsmlConnection extends LDAPConnection {
//First print the SOAP Envelope
pout.println("<?xml version=\"1.0\" encoding=\"UTF8\"?>");
pout.println("<soap-env:Envelope xmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\">");
pout.println("<soap-env:Body>");
if (this.useSoap) {
pout.println("<soap-env:Envelope xmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\">");
pout.println("<soap-env:Body>");
}
//write out the message
//writer.writeMessage(message);
//writer.finish();
pout.write(DSML);
//Complete the SOAP Envelope
pout.println("</soap-env:Body>");
pout.println("</soap-env:Envelope>");
if (this.useSoap) {
//Complete the SOAP Envelope
pout.println("</soap-env:Body>");
pout.println("</soap-env:Envelope>");
}
StringBufferInputStream in = new StringBufferInputStream(out.toString());
//Set the input stream
......@@ -271,6 +279,7 @@ public class DsmlConnection extends LDAPConnection {
public DsmlConnection(){
this.con = new HttpClient();
this.con.getState().setAuthenticationPreemptive(true);
this.useSoap = true;
}
......@@ -855,4 +864,16 @@ public class DsmlConnection extends LDAPConnection {
public String getServerString() {
return serverString;
}
/**
* @return Returns the useSoap.
*/
public boolean isUseSoap() {
return useSoap;
}
/**
* @param useSoap The useSoap to set.
*/
public void setUseSoap(boolean useSoap) {
this.useSoap = useSoap;
}
}
......@@ -90,6 +90,8 @@ implements Externalizable
*/
/* package */
LDAPSearchResults( LDAPConnection conn,
LDAPSearchQueue queue,
LDAPSearchConstraints cons)
......
This diff is collapsed.
/* **************************************************************************
*
* Copyright (C) 2005 Marc Boorshtein, Inc. All Rights Reserved.
*
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
* TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
* TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
* AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
* IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
* OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
* PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM OCTET STRING, INC.,
* COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
******************************************************************************/
package com.novell.ldap;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.openspml.message.Attribute;
import org.openspml.message.Identifier;
import org.openspml.message.SearchResult;
import com.novell.ldap.util.LDAPReader;
/**
* @author Marc Boorshtein
*
* Used as a drop-in replacement for LDAPSerchResults
*/
public class SPMLSearchResults extends LDAPSearchResults {
/** The returned controls */
LDAPControl[] controls;
/** The response pointer */
int msgRespPtr;
List results;
/** The last read message */
SearchResult lastread;
/** Are there no results? */
boolean empty;
/** Have any results been read? */
boolean wasRead;
Iterator iter;
public SPMLSearchResults(List results) {
this.results = results;
this.iter = results.iterator();
this.empty = false;
this.wasRead = true;
}
public SPMLSearchResults() {
this.empty = true;
this.wasRead = true;
}
/* (non-Javadoc)
* @see com.novell.ldap.LDAPSearchResults#abandon()
*/
void abandon() {
}
/* (non-Javadoc)
* @see com.novell.ldap.LDAPSearchResults#getCount()
*/
public int getCount() {
return 0;
}
/* (non-Javadoc)
* @see com.novell.ldap.LDAPSearchResults#getResponseControls()
*/
public LDAPControl[] getResponseControls() {
return controls;
}
/* (non-Javadoc)
* @see com.novell.ldap.LDAPSearchResults#hasMore()
*/
public boolean hasMore() {
return this.iter.hasNext();
}
/* (non-Javadoc)
* @see com.novell.ldap.LDAPSearchResults#next()
*/
public LDAPEntry next() throws LDAPException {
SearchResult res = (SearchResult) iter.next();
Map attribs = res.getAttributeMap();
Iterator it = attribs.keySet().iterator();
LDAPAttributeSet attribSet = new LDAPAttributeSet();
while (it.hasNext()) {
String name = (String) it.next();
Object o = attribs.get(name);
if (o instanceof String) {
String attrib = (String) attribs.get(name);
LDAPAttribute ldapAttrib = new LDAPAttribute(name);
if (attrib == null) {
attrib = "";
}
ldapAttrib.addValue(attrib);
attribSet.add(ldapAttrib);
} else if (o instanceof List) {
List l = (List) attribs.get(name);
Iterator vals = l.iterator();
LDAPAttribute ldapAttrib = new LDAPAttribute(name);
while (vals.hasNext()) {
String attrib = (String) vals.next();
if (attrib == null) {
attrib = "";
}
ldapAttrib.addValue(attrib);
}
attribSet.add(ldapAttrib);
}
}
Identifier id = res.getIdentifier();
LDAPAttribute ldapAttrib = new LDAPAttribute(id.getType().substring(id.getType().lastIndexOf('#') + 1));
ldapAttrib.addValue(id.getId());
attribSet.add(ldapAttrib);
LDAPEntry ret = new LDAPEntry(id.getType().substring(id.getType().lastIndexOf('#') + 1) + "=" + id.getId(),attribSet);
return ret;
}
}
This diff is collapsed.
/* **************************************************************************
*
* Copyright (C) 2005 Marc Boorshtein, Inc. All Rights Reserved.
*
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
* TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
* TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
* AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
* IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
* OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
* PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM OCTET STRING, INC.,
* COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
******************************************************************************/
package com.novell.ldap.spml;
import org.openspml.client.SpmlClient;
import com.novell.ldap.LDAPException;
/**
* @author mboorshtei002
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class NoAuthImpl implements SPMLImpl {
SpmlClient con;
/* (non-Javadoc)
* @see com.novell.ldap.spml.SPMLImpl#getSpmlClient()
*/
public SpmlClient getSpmlClient() {
if (con == null) {
con = new SpmlClient();
}
return con;
}
/* (non-Javadoc)
* @see com.novell.ldap.spml.SPMLImpl#login(java.lang.String, java.lang.String)
*/
public void login(String username, String password) throws LDAPException {
//Do nothing
}
/* (non-Javadoc)
* @see com.novell.ldap.spml.SPMLImpl#logout()
*/
public void logout() throws LDAPException {
//Do nothing
}
public static void main(String[] args) {
}
}
/* **************************************************************************
*
* Copyright (C) 2005 Marc Boorshtein, Inc. All Rights Reserved.
*
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
* TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
* TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
* AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
* IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
* OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
* PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM OCTET STRING, INC.,
* COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
******************************************************************************/
package com.novell.ldap.spml;
import org.openspml.client.SpmlClient;
import com.novell.ldap.LDAPException;
/**
* @author Marc Boorshtein
*
* Base interface for accessing vendor specific SPML
* implementation classes
*
*/
public interface SPMLImpl {
/**
* Returns the implementation of the SpmlClient
* @return
*/
public SpmlClient getSpmlClient();
/**
* Performs a login
* @param username The user's name
* @param password The user's password
*/
public void login(String username,String password) throws LDAPException;
public void logout() throws LDAPException;
}
/* **************************************************************************
*
* Copyright (C) 2005 Marc Boorshtein, Inc. All Rights Reserved.
*
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
* TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
* TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
* AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
* IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
* OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
* PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM OCTET STRING, INC.,
* COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
******************************************************************************/
package com.novell.ldap.spml;
import org.openspml.client.LighthouseClient;
import org.openspml.client.SpmlClient;
import org.openspml.util.SpmlException;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPLocalException;
/**
* @author mboorshtei002
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class SunIdm implements SPMLImpl{
LighthouseClient con;
/* (non-Javadoc)
* @see com.novell.ldap.spml.SPMLImpl#getSpmlClient()
*/
public SpmlClient getSpmlClient() {
if (con == null) {
this.con = new LighthouseClient();
}
return con;
}
/* (non-Javadoc)
* @see com.novell.ldap.spml.SPMLImpl#login(java.lang.String, java.lang.String)
*/
public void login(String username, String password) throws LDAPException {
try {
con.setUser(username);
con.setPassword(password);
con.login();
} catch (SpmlException e) {
throw new LDAPLocalException("Error logging in", LDAPException.INVALID_CREDENTIALS, e);
}
}
/* (non-Javadoc)
* @see com.novell.ldap.spml.SPMLImpl#logout()
*/
public void logout() throws LDAPException {
try {
con.logout();
} catch (SpmlException e) {
throw new LDAPLocalException("Error logging out", 53, e);
}
}
}
......@@ -41,7 +41,7 @@ public class DSMLWriter implements LDAPWriter {
private boolean indent = false;
private String tabString = " ";
private String version = "2.0";
private boolean useSOAP;
private boolean resumeOnError;
private static final String BATCH_REQUEST_START =
......@@ -1477,5 +1477,17 @@ public class DSMLWriter implements LDAPWriter {
return ret;
}
/**
* @return Returns the useSOAP.
*/
public boolean isUseSOAP() {
return useSOAP;
}
/**
* @param useSOAP The useSOAP to set.
*/
public void setUseSOAP(boolean useSOAP) {
this.useSOAP = useSOAP;
}