| Oracle® Fusion Middleware Oracle Identity Managementアプリケーション開発者ガイド 11g リリース1 (11.1.1) B56242-07 |
|
![]() 前 |
![]() 次 |
この章では、Java Naming and Directory Interface (JNDI)に対するJava API拡張機能を使用して、第3章で紹介した多くの操作を実行する方法について説明します。
標準APIに対するOracleの拡張機能の詳細は、『Oracle Fusion Middleware Java API Reference for Oracle Internet Directory』を参照してください。
この章の内容は次のとおりです。
Java拡張機能は、LDAPクライアントのインストール時に標準のJava APIとともにインストールされます。APIとその拡張機能は、$ORACLE_HOME/jlib/ldapjclnt10.jarにあります。
Javaでは、LDAPエンティティ(ユーザー、グループ、レルム、アプリケーション)は、ハンドルではなくJavaオブジェクトとしてモデル化されます。このモデル化は、oracle.java.utilパッケージで行われます。他のすべてのユーティリティ機能は、個々のオブジェクトとして(GUIDなど)、あるいはユーティリティ・クラスの静的メンバー関数としてモデル化されます。
たとえば、ユーザーを認証するには、アプリケーションは次の手順に従います。
指定されたユーザー識別名で、oracle.ldap.util.Userオブジェクトを作成します。
必要なプロパティのすべてを備えたDirContext JNDIオブジェクトを作成するか、あるいはDirContextオブジェクトのプールからJNDIオブジェクトを取得します。
User.authenticateUserメソッドを呼び出して、DirContextオブジェクトおよびユーザー資格証明への参照を渡します。
既存のDirContextオブジェクトのプールから取得したDirContextオブジェクトは、そのプールに戻します。
CやPL/SQLのプログラマとは異なり、Javaプログラマはオブジェクトを明示的に解放する必要がありません。このタスクは、Javaのガベージ・コレクション・メカニズムが実行します。
Userクラス、SubscriberクラスおよびGroupクラスのほとんどのメソッドは、PropertySetCollectionオブジェクトを戻します。このオブジェクトは、1つ以上のLDAPエントリの集合を表しています。各エントリはPropertySetオブジェクトで表され、識別名で識別されます。PropertySetには、Propertyとして表される属性が含まれる場合があります。Propertyとは、そのPropertyが表す特定の属性に関する1つ以上の値の集合です。次に、これらのクラスの使用例を示します。
PropertySetCollection psc = Util.getGroupMembership( ctx,
myuser,
null,
true );
// for loop to go through each PropertySet
for (int i = 0; i < psc.size(); i++ ) {
PropertySet ps = psc.getPropertySet(i);
// Print the DN of each PropertySet
System.out.println("dn: " + ps .getDN());
// Get the values for the "objectclass" Property
Property objectclass = ps.getProperty( "objectclass" );
// for loop to go through each value of Property "objectclass"
for (int j = 0; j< objectclass.size(); j++) {
// Print each "objectclass" value
System.out.println("objectclass: " + objectclass.getValue(j));
}
}
エンティティmyuserは、Userオブジェクトです。pscオブジェクトには、myuserが属するネストされたグループがすべて含まれます。このコードは結果エントリをループし、各エントリのオブジェクト・クラス値をすべて出力します。
ユーザー関連機能はすべてoracle.ldap.util.UserというJavaクラスで抽象化されます。このプロセスは、次のようになります。
識別名、GUIDまたは単純な名前に基づいて、oracle.ldap.util.Userオブジェクトを構成します。
必要な場合は、User.authenticateUser(DirContext, int, Object)を呼び出して、ユーザーを認証します。
User.getProperties(DirContext)を呼び出して、ユーザー・エントリの属性を取得します。
User.getExtendedProperties(DirContext, int, String[])を起動してユーザーの拡張プロパティを取得します。intはsharedまたはapplication-specificのどちらかです。String[]は必要なプロパティのタイプを表すオブジェクトです。String[]がnullの場合、指定されたカテゴリのすべてのプロパティが取得されます。
PropertySetCollection.getProperties(int)を呼び出して、手順4で戻されたプロパティの解析に必要なメタデータを取得します。
拡張プロパティを解析し、アプリケーション固有のロジックを続行します。この解析は、アプリケーション固有のロジックによっても行われます。
ユーザー認証は、ユーザーがログイン時に指定した資格証明とそのユーザーのディレクトリ内の資格証明を比較する一般的なLDAP操作です。Oracle Internet Directoryでは、次のものがサポートされています。
認証時に使用可能な任意の属性。
認証メソッドによって戻される任意のパスワード・ポリシー例外。ただし、パスワード・ポリシーはuserpassword属性のみに適用されることに注意してください。
次に、APIを使用してユーザーを認証するためのコード例を示します。
// User user1 - is a valid User Object
try
{
user1.authenticateUser(ctx,
User.CREDTYPE_PASSWD, "welcome");
// or
// user1.authenticateUser(ctx, <any
attribute>, <attribute value>);
}
catch (UtilException ue)
{
// Handle the password policy error
accordingly
if (ue instanceof PasswordExpiredException)
// do something
else if (ue instanceof GraceLoginException)
// do something
}
subscriberクラスによってcreateUser()メソッドが使用され、プログラムによりユーザーが作成されます。ユーザー・エントリに必要なオブジェクト・クラスは、Oracle Delegated Administration Servicesを介して設定可能です。createUser()メソッドは、ユーザーの作成時に、クライアントが要件を理解し必須の属性に対して値を提供することを前提にしています。プログラマによって必須情報が提供されない場合、サーバーはエラーを戻します。
コード例の次のスニペットは、使用方法を示します。
// Subscriber sub is a valid Subscriber object // DirContext ctx is a valid DirContext // Create ModPropertySet object to define all the attributes and their values. ModPropertySet mps = new ModPropertySet(); mps.addProperty(LDIF.ATTRIBUTE_CHANGE_TYPE_ADD,"cn", "Anika"); mps.addProperty(LDIF.ATTRIBUTE_CHANGE_TYPE_ADD,"sn", "Anika"); mps.addProperty(LDIF.ATTRIBUTE_CHANGE_TYPE_ADD,"mail", "Anika@example.com"); // Create user by specifying the nickname and the ModPropertySet just defined User newUser = sub.createUser( ctx, mps, true); // Print the newly created user DN System.out.println( newUser.getDN(ctx) ); // Perform other operations with this new user
subscriberクラスによってgetUser()メソッドが提供され、Userクラスのパブリック・コンストラクタと置き換えられます。このメソッドは、指定された情報に基づいてUserオブジェクトを戻します。
次に、使用方法を示します。
// DirContext ctx is contains a valid directory connection with sufficient privilege to perform the operations // Creating RootOracleContext object RootOracleContext roc = new RootOracleContext(ctx); // Obtain a Subscriber object representing the default subscriber Subscriber sub = roc.getSubscriber(ctx, Util.IDTYPE_DEFAULT, null, null); // Obtain a User object representing the user whose nickname is "Anika" User user1 = sub.getUser(ctx, Util.IDTYPE_SIMPLE, "Anika", null); // Do work with this user The getUser() method can retrieve users based on DN, GUID and simple name. A getUsers() method is also available to perform a filtered search to return more than one user at a time. The returned object is an array of User objects. For example, // Obtain an array of User object where the user's nickname starts with "Ani" User[] userArr = sub.getUsers(ctx, Util.IDTYPE_SIMPLE, "Ani", null); // Do work with the User array
この項では、Java APIを使用してアイデンティティ管理レルムのオブジェクトを取得する方法について説明します。
RootOracleContextクラスはルートOracleコンテキストを表します。アイデンティティ管理レルムの作成に必要な情報のほとんどは、ルートOracleコンテキストに格納されています。RootOracleContextクラスではgetSubscriber()メソッドが提供されます。このメソッドは、subscriberクラスのパブリック・コンストラクタと置き換えられ、指定された情報に基づいてアイデンティティ管理レルム・オブジェクトを戻します。
次に、使用方法を示します。
// DirContext ctx contains a valid directory // connection with sufficient privilege to perform the // operations // Creating RootOracleContext object RootOracleContext roc = new RootOracleContext(ctx); // Obtain a Subscriber object representing the // Subscriber with simple name "Oracle" Subscriber sub = roc.getSubscriber(ctx, Util.IDTYPE_SIMPLE, "Oracle", null); // Do work with the Subscriber object
次の例では、単純な名前、GUIDまたはDNがわかっている場合にユーザーのログイン名を検索する方法を示します。Oracle Single Sign-Onのログイン名は、ニックネームとも呼ばれます。
この例は、2つの部分から構成されています。
このレルムへのニックネームの保存に使用されている属性を確認します。
ユーザー・オブジェクトを取得し、ニックネーム属性の値を確認します。
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import oracle.ldap.util.jndi.*;
import oracle.ldap.util.*;
import java.io.*;
public class NickNameSearch {
public static void main(String[] args)
throws Exception
{
InitialLdapContext ctx = ConnectionUtil.getDefaultDirCtx( args[0],
args[1], args[2],args[3]);
RootOracleContext roc=new RootOracleContext(ctx);
Subscriber sub = null;
sub = roc.getSubscriber(ctx, Util.IDTYPE_DEFAULT, null, null) ;
PropertySetCollection psc = sub.getProperties(ctx,
Subscriber.USER_NAMING_PROPERTIES, null);
String nickNameAttribute = null;
try
{
nickNameAttribute = (String) psc.getPropertySet(0).getProperty(Subscriber.USER_NAMING_ATTR_SIMPLE).getValue(0);
}
catch (Exception e)
{
// unable to retrieve the attribute name
System.exit(0);
}
System.out.println("Nickname attribute: " + nickNameAttribute);
// Retrieve user using simple name, guid or DN
User user = sub.getUser(ctx, Util.IDTYPE_SIMPLE,"orcladmin", null);
System.out.println("user DN: " + user.getDN(ctx));
// Retrieve nickname value using User object
psc = user.getProperties(ctx, new String[]{ nickNameAttribute });
String nickName = null;
try
{
nickName = (String) psc.getPropertySet(0).getProperty(nickNameAttribute).getValue(0);
}
catch (Exception e)
{
// unable to retrieve the attribute value
System.exit(0);
}
System.out.println("Nickname : " + nickName);
}
}
次の新しいJavaクラス(パブリック・クラス)が導入されました。
public class oracle.ldap.util.discovery.DiscoveryHelper
このクラスでは、指定されたソースから特定の情報を検出するメソッドが提供されます。
表5-1 ディレクトリ・サーバー検出のメソッド
| メソッド | 説明 |
|---|---|
discover |
指定されたソースから特定の情報を検出します。 |
setProperty |
検出に必要なプロパティを設定します。 |
getProperty |
プロパティの値にアクセスします。 |
既存のJavaクラスoracle.ldap.util.jndi.ConnectionUtilに、次の2つの新しいメソッドが追加されます。
getDefaultDirCtx: オーバーロードされたこのファンクションでは、oracle.ldap.util.discovery.DiscoveryHelper.discover()に対して内部コールを実行して、SSL以外のLDAPサーバーのホスト名およびポート情報が判断されます。
getSSLDirCtx: オーバーロードされたこのファンクションでは、oracle.ldap.util.discovery.DiscoveryHelper.discover()に対して内部コールを実行して、SSLのLDAPサーバーのホスト名およびポート情報が判断されます。
次に、ディレクトリ・サーバー検出に使用するJavaプログラムの例を示します。
import java.util.*;
import java.lang.*;
import oracle.ldap.util.discovery.*;
import oracle.ldap.util.jndi.*;
public class dsdtest
{
public static void main(String s[]) throws Exception
{
HashMap reshdl = new HashMap();
String result = new String();
Object resultObj = new Object();
DiscoveryHelper disco = new
DiscoveryHelper(DiscoveryHelper.DNS_DISCOVER);
// Set the property for the DNS_DN
disco.setProperty(DiscoveryHelper.DNS_DN,"dc=us,dc=fiction,dc=com")
;
// Set the property for the DNS_DISCOVER_METHOD
disco.setProperty(DiscoveryHelper.DNS_DISCOVER_METHOD,
DiscoveryHelper.USE_INPUT_DN_METHOD);
// Set the property for the SSLMODE
disco.setProperty(DiscoveryHelper.SSLMODE,"0");
// Call the discover method
int res=disco.discover(reshdl);
if (res!=0)
System.out.println("Error Code returned by the discover method is :"+res) ;
// Print the results
printReshdl(reshdl);
}
public static void printReshdl(HashMap reshdl)
{
ArrayList result = (ArrayList)reshdl.get(DiscoveryHelper.DIR_SERVERS);
if (result != null)
{
if (result.size() == 0) return;
System.out.println("The hostnames are :-");
for (int i = 0; i< result.size();i++)
{
String host = (String)result.get(i);
System.out.println((i+1)+".
'"+host+"'");
}
}
}
}
JNDIを使用してSASL接続を確立する場合、javax.naming.Contextの次のプロパティを設定する必要があります。
Context.SECURITY_AUTHENTICATION = "DIGEST-MD5"
Context.SECURITY_PRINCIPAL
後者にはプリンシパル名を設定します。この名前は、サーバー固有の形式です。次のいずれかのようになります。
認証されているエンティティの完全に修飾された識別名が続く識別名dn:
ユーザー識別子が続く文字列u:
Oracleディレクトリ・サーバーは、完全に修飾された識別名(cn=user,ou=my department,o=my companyなど)のみを受け入れます。
|
注意: SASL識別名は、SASLバインドをコールするAPIに渡される前に正規化される必要があります。SASLベリファイアを生成するために、Oracle Internet Directoryでは正規化された識別名のみがサポートされます。 |
次のコードでは、SASL Digest-MD5を使用したJava LDAP/JNDIの例を示します。
/* $Header: LdapSasl.java 27-oct-2005.11:26:59 qdinh Exp $ */
/* Copyright (c) 2003, 2005, Oracle. All rights reserved. */
/*
DESCRIPTION
<short description of component this file declares/defines>
PRIVATE CLASSES
<list of private classes defined - with one-line descriptions>
NOTES
<other useful comments, qualifications, and so on.>
MODIFIED (MM/DD/YY)
qdinh 04/23/03 - Creation
*/
/**
* @version $Header: LdapSasl.java 27-oct-2005.11:26:59 qdinh Exp $
* @author qdinh * @since release specific (what release of product did this appear in)
*/
package oracle.ldap.util.jndi;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import oracle.ldap.util.jndi.*;
import oracle.ldap.util.*;
import java.lang.*;
import java.util.*;
public class LdapSasl
{
public static void main( String[] args)
throws Exception
{
int numofargs;
numofargs = args.length;
Hashtable hashtable = new Hashtable();
// Look through System Properties for Context Factory if it is available
// then set the CONTEXT factory only if it has not been set
// in the environment -
// set default to com.sun.jndi.ldap.LdapCtxFactory
hashtable.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
// possible valid arguments
// args[0] - hostname
// args[1] - port number
// args[2] - Entry DN
// args[3] - Entry Password
// args[4] - QoP [ auth | auth-int | auth-conf ]
// args[5] - SASL Realm
// args[6] - Cipher Choice
// If QoP == "auth-conf" then args[6] cipher choice can be
// - des
// - 3des
// - rc4
// - rc4-56
// - rc4-40
hashtable.put(Context.PROVIDER_URL, "ldap://"+args[0]+":"+args[1]);
hashtable.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5");
System.out.println("hash put security dn: " + args[2]);
hashtable.put(Context.SECURITY_PRINCIPAL, args[2] );
hashtable.put(Context.SECURITY_CREDENTIALS, args[3] );
// For Quality of Protection modes
// 1. Authentication and Data Integrity Mode - "auth-int"
// 2. Authentication and Data Confidentiality Mode "auth-conf"
//
// hashtable.put("javax.security.sasl.qop",args[4]);
hashtable.put("javax.naming.security.sasl.realm", args[5]);
// Setup Quality of Protection
//
// System.out.println("hash sasl.qop: " + args[4]);
hashtable.put("javax.security.sasl.qop",args[4]);
if (numofargs > 4)
{
if (args[4].equalsIgnoreCase("AUTH-CONF"))
{
// Setup a cipher choice only if QoP == "auth-conf"
String strength = "high";
String cipher = new String(args[6]);
if (cipher.compareToIgnoreCase("rc4-40") == 0)
strength = "low";
else if (cipher.compareToIgnoreCase("rc4-56") == 0 ||
cipher.compareToIgnoreCase("des")== 0 )
strength = "medium";
else if (cipher.compareToIgnoreCase("3des") == 0 ||
cipher.compareToIgnoreCase("rc4") == 0)
strength = "high";
// setup cipher choice
System.out.println("hash sasl.strength:"+strength);
hashtable.put("javax.security.sasl.strength",strength);
}
// set maxbuffer length if necessary
if (numofargs > 7 && !"".equals(args[6]))
hashtable.put("javax.security.sasl.maxbuf", args[5].toString());
}
// Enable Debug --
// hashtable.put("com.sun.jndi.ldap.trace.ber", System.err);
LdapContext ctx = new InitialLdapContext(hashtable,null);
// At this stage - SASL Digest -MD5 has been successfully
System.out.println("sasl bind successful");
// Ldap Search Scope Options
//
// - Search base - OBJECT_SCOPE
// - One Level - ONELEVEL_SCOPE
// - Sub Tree - SUBTREE_SCOPE
//
// Doing an LDAP Search
PropertySetCollection psc = Util.ldapSearch(ctx,"o=oracle,dc=com","objectclass=*",SearchControls.OBJECT_SCOPE,
new String[] {"*"});
// Print out the serach result
Util.printResults(psc);
System.exit(0);
} }
11gリリース1(11.1.1.6)の時点で、Oracle Internet Directory SDKはRFC 5805に定義されているトランザクションをサポートしています。
トランザクションはプロビジョニングなどいくつかのアプリケーションをサポートする必要があります。トランザクションがコミットされた場合、トランザクション更新内のすべての操作が成功するか、すべて失敗するかのいずれかです。Oracle Internet Directoryは、拡張操作およびコントロールのオブジェクト識別子を、ルートDSEでsupportedExtensionおよびsupportedControlとして公開します。
Oracle Internet Directory LDAPトランザクションは次のエンティティを使用します。
トランザクション開始リクエスト(オブジェクト識別子 1.3.6.1.1.21.1): トランザクション開始に関連した操作のグループ化を容易にするLDAP拡張操作です。これはrequestNameが1.3.6.1.1.21.1でrequestValueが存在しないCHOICE extendedReqのLDAPMessageです。
トランザクション開始レスポンス: トランザクション開始リクエストへのレスポンス内でOracle Internet Directoryサーバーから送信されます。これはCHOICE extendedResのLDAPMessageです。このresponseNameは存在しません。成功した場合、resultCode(0)、responseValueは存在しトランザクション識別子を保持しています。リクエスト形式が不正などの理由で失敗した場合、responseValueは存在しません。
トランザクション仕様コントロール(オブジェクト識別子 1.3.6.1.1.21.2): このコントロールの値であるトランザクション識別子により、操作とトランザクションの関連を示すLDAPControlです。このcriticalityはTRUEです。
トランザクション終了リクエスト(オブジェクト識別子 1.3.6.1.1.21.3): トランザクションの終了を示すために使用される、もう1つのLDAP拡張操作です。このトランザクションの処理(トランザクションのコミットまたは中断)を示します。このLDAPMessageはrequestNameが1.3.6.1.1.21.3でrequestValueが存在するCHOICE extendedReqを保持し、BERでエンコードされたトランザクション・リクエストを格納します。
コミットの値がTRUEの場合、識別子で識別されたトランザクションをコミットするリクエストです。コミットの値がFALSEの場合、識別されたトランザクションを中断するリクエストです。
トランザクション終了レスポンス: Oracle Internet Directoryサーバーのトランザクション終了リクエストへのLDAPMessageレスポンスです。このレスポンス名は存在しません。responseValueが存在する場合、これにはBERでエンコードされたトランザクション・レスポンスが格納されます。
トランザクション中断通知(オブジェクト識別子 1.3.6.1.1.21.4): トランザクション識別子を含む、responseNameが1.3.6.1.1.21.4でresponseValueが存在する要求に基づかない通知メッセージです。
LDAPトランザクション内でのOracle Internet Directoryサーバーとクライアント間のリクエストおよびレスポンスの順序を次に示します。
クライアントが、Oracle Internet Directoryサーバーにトランザクション開始リクエストを発行します。
Oracle Internet Directoryサーバーが、トランザクション開始レスポンスにトランザクション識別子を設定し、成功のresultCode(0)でこのリクエストに応答します。不正な形式のリクエストなどの理由で失敗した場合、サーバーはエラーの種類を示す成功以外のresultCodeを含むトランザクション開始レスポンスで応答します。
成功した場合に生成されてクライアントに送信されるこのトランザクション識別子は、後続のプロトコル・メッセージでこのトランザクションを識別するために使用されます。
クライアントはサーバーから成功の結果コードを受け取ると、トランザクション識別子を持ったトランザクション仕様コントロールを各更新操作に添付して、単一トランザクションの一部として処理される操作であることを示します。有効な場合のレスポンスでは、Oracle Internet Directoryは成功を送信します。無効の場合、エラーの種類の詳細とともにresultCodeを含む、リクエストへの適切なレスポンスをクライアントに送信します。
クライアントは、トランザクション識別子を持ったトランザクション仕様コントロールが添付された、すべてのトランザクション更新操作をOracle Internet Directoryサーバーに送信すると、トランザクション識別子を格納したトランザクション終了リクエストをOracle Internet Directoryサーバーに送信し、トランザクションの処理を要求します。コミットの値がTRUEの場合はトランザクションをコミットするリクエストを表し、値がFALSEの場合はトランザクションを中断するリクエストを表します。
トランザクション中断のリクエストを受信すると、Oracle Internet Directoryサーバーは識別されたトランザクションを構成するすべての操作を破棄してトランザクションを中断し、成功のresultCode(0)を含むトランザクション終了レスポンスを返すことで処理の完了を表します。トランザクションをコミットするリクエストを受信すると、Oracle Internet DirectoryサーバーはDBに対して、トランザクション内のすべての操作に対して行った更新をコミットします。成功した場合、サーバーは、成功のresultCode(0)を含むトランザクション終了レスポンスを戻します。失敗した場合は、失敗の種類を表す成功以外のresultCodeを含むトランザクション終了レスポンスを戻します。
トランザクション外でリクエストされたトランザクションや更新をサーバーがシリアライズする必要はありません。つまり、サーバーは1つ以上のクライアントからの異なるエントリ・セット上で動作する複数のコミット・リクエストを同時に処理することがあります。
前述のクライアントとサーバーとのやりとりの際、サーバーがトランザクションの仕様を継続できなくなった場合、サーバーはトランザクション中断通知を発行します。この通知を受信すると、クライアントはトランザクション識別子の使用をすべて中止する必要があり、トランザクションはnullおよびvoidとなります。トランザクションの一部として処理が予定されていたすべての操作は暗黙的に破棄されます。クライアントが引き続きこの識別子を使用しても、Oracle Internet Directoryサーバーからは失敗のresultCodeを含むレスポンスが戻されます。
前述のクライアントとサーバーとのやりとりの際、クライアントがOracle Internet Directoryサーバーへの接続を閉じた場合、サーバーは必要な接続関連のクリーンアップを実行します。
この項では、LDAP拡張操作を使用したJNDIベースのLDAPトランザクションJavaクライアント・モジュールの開発に必要な手順の簡単なアウトラインを説明します。手順では、トランザクション開始リクエスト、トランザクション開始レスポンス、トランザクション終了リクエストおよびトランザクション終了レスポンスの4つのインタフェースの実装を行います。これら4つのインタフェースを実装するクラスは、トランザクション・セマンティクス内でLDAP更新操作を実行するコードで使用される必要があります。次のサンプルのコード・スニペットは、実装される4つのインタフェースと、トランザクション・セマンティクスでのLDAP更新操作のサンプルにおけるこれらの使用方法を示します。
import java.lang.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
public class LdapStartTxnReq implements ExtendedRequest
{
public static final String TXN_REQ_OID = "1.3.6.1.1.21.1";
// constructor
public LdapStartTxnReq()
{
}
// Method for getting the request ID
public String getID() {
return TXN_REQ_OID;
}
public byte[] getEncodedValue() {
return null; // No value is needed for Start Txn request
}
public ExtendedResponse createExtendedResponse(String id, byte[] berValue,
int offset, int length)
throws NamingException
{
return new LdapStartTxnRes(id, berValue, offset, length); }
}
import java.lang.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
public class LdapStartTxnRes implements ExtendedResponse
{
public String txnID;
// Called by LdapStartTxnReq.createExtendedResponse()
protected LdapStartTxnRes(String id, byte[] berValue, int offset, int length)
throws NamingException
{
byte[] buff2 = new byte[length];
System.arraycopy(berValue, offset, buff2, 0, length);
try
{
this.txnID = new String(berValue, "UTF8");
}
catch (Exception e)
{
System.out.println(e);
}
}
public String getTxnID()
{
return txnID;
}
// No op for our case
public byte[] getEncodedValue()
{
return null;
}
public String getID()
{
return null; // as have no response ID.
}
}
import java.lang.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.naming.ldap.*;
import oracle.ldap.util.ber.*;
public class LdapEndTxnReq implements ExtendedRequest
{
public static final String TXN_END_REQ_OID = "1.3.6.1.1.21.3";
private int sequenceTag = 0x30;
private boolean commitValue;
private String controlValue;
// constructor
public LdapEndTxnReq(boolean commitVal, String controlVal)
{
this.commitValue = commitVal;
this.controlValue = controlVal;
}
// Method to get End Txn Request ID
public String getID() {
return TXN_END_REQ_OID;
}
public byte[] getEncodedValue()
{
boolean encodeUTF8 = true;
byte[] bytes = null;
try
{
BEREncoder berElement = new BEREncoder();
berElement.beginSeq(sequenceTag);
berElement.encodeBoolean(this.commitValue);
berElement.encodeString(this.controlValue, encodeUTF8);
berElement.endSeq();
bytes = berElement.getTrimmedBuf();
return bytes;
}
catch (EncodeException e)
{
return null;
}
}
public ExtendedResponse createExtendedResponse(String id, byte[] berValue,
int offset, int length)
throws NamingException
{
return null;
}
}
import java.lang.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
public class LdapEndTxnRes implements ExtendedResponse
{
// constructor
LdapEndTxnRes(String id, byte[] berValue, int offset, int length)
throws NamingException
{
;
}
public String getTxnID()
{
return null;
}
public byte[] getEncodedValue()
{
return null;
}
public String getID()
{
return null;
}
}
import java.lang.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
.
.
.
public class LdapTxnOperation implements …………….
{
public static void main( String[] args )
{
try
{
LdapContext ctx;
Perform ldapbind against OID server on the LDAP context ctx;
If bind is successful
{
/* Issue LDAP Start Transaction Request to OID server and
receive its response */
LdapStartTxnRes startResp = (LdapStartTxnRes)ctx.extendedOperation(new LdapStartTxnReq());
/* Extract the transaction ID sent by OID server */
String txnID = startResp.getTxnID();
Issue LDAP update operations (add, delete, modify) to OID server each containing
the Transaction Control with ID 1.3.6.1.1.21.2 and value of the transaction ID;
/* Vendor's technical doc link is provided in Reference section below */
/* After done sending all update operations, issue LDAP End Transaction Request
to OID server with your intention to either commit or abort the transaction and
receive its response. */
If want to commit the transaction
{ /* commit request */
LdapEndTxnRes endResp = (LdapEndTxnRes)ctx.extendedOperation(new LdapEndTxnReq(true, txnID));
}
Else
{ /* abort request */
LdapEndTxnRes endResp = (LdapEndTxnRes)ctx.extendedOperation(new LdapEndTxnReq(false, txnID));
}
}
catch( Exception e)
{
e.printStackTrace();
return;
}
return ;
}
}