Showing posts with label LDAP Programming. Show all posts
Showing posts with label LDAP Programming. Show all posts

Thursday, October 2, 2008

What are the Oracle Identity Management APIs available for Application Integration?

  1. Oracle Internet Directory provides LDAP APIs for C, Java, and PL/SQL.
  2. Oracle Delegated Administration Services provides a number of services for building customized administration interfaces such as User LOV that manipulate directory data.
  3. OracleAS Single Sign-On provides APIs for developing and deploying partner applications
  4. JAZN is the Oracle implementation of the Java Authentication and Authorization Service (JAAS) Support standard. JAZN allows applications developed for the Web using the Oracle J2EE environment to use the identity management infrastructure for authentication and authorization.

What useful information can be extracted from ODS Schema?

I. Get user’s full name
You can get the information from ods.ds_attrstore. For example:
SELECT o.entryid,
UPPER(o.attrval) user_name,
(SELECT first.attrval FROM ODS.DS_ATTRSTORE first WHERE first.attrname = 'givenname' AND first.entryid
= o.entryid) first_name,
(SELECT last.attrval FROM ODS.DS_ATTRSTORE last WHERE last.attrname = 'sn' AND last.entryid = o.entryid)
last_name
FROM ODS.DS_ATTRSTORE o
WHERE o.attrname = 'uid'

II. How to Get other Attribute Values?
Attribute values are stored in ods.ct_ATTRIBUTE_NAME table

Tuesday, September 30, 2008

How to protect ROOT user password in production & connect to LDAP server?

Step 1:
Add the entry in web.xml of the J2EE project
<env-entry> 
<description>
Password for jndi
</description> 
<env-entry-name>
jndi-password
</env-entry-name> 
<env-entry-value>
welcome123
</env-entry-value> 
<env-entry-type>
java.lang.String
</env-entry-type> 
</env-entry>
Step 2:
Lookup the password by using JNDI lookup as following

Context initial = new InitialContext(); 
Context environment = (Context)initial.lookup("java:comp/env"); 
String password = (String)environment.lookup("jndi-password");

Step 3:
Deploy the application in an OC4J using Enterprise Manager. For eg. I have deployed the application “HomePortlet” in oc4j_test.

Step 4: Navigate to the web module of the application, Click on environment link as shown below

Step 5: Update the “Deployed Value” in the environment entries heading and click “apply”.

LDAP API Programming Best Practices

We recently had problems with load on our single sign on (SSO) server. There were 100s of open LDAP connections to our LDAP servers.
By looking at the LDAP code there are two places where we make LDAP connections, or, as they are known in Java contexts.

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://hostname.com");
LdapContext ctx = new InitialLdapContext(env,null);
// do something with ctx
ctx.close()

The contexts were always closed and this is where LDAP connection pooling came into the picture.
env.put("com.sun.jndi.ldap.connect.pool", "true");
This turns on connection pooling. The following code is for your reference

DirContext ctx=null;
NamingEnumeration answers=null;
Properties env = new Properties();
//Bind the context
env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
env.put( Context.PROVIDER_URL, "ldap://" + bundle.getString("LDAP_SERVER") + ":" +
bundle.getString("LDAP_PORT") + "/");
env.put( Context.SECURITY_PRINCIPAL, bundle.getString("ROOTDN") );
// env.put( Context.SECURITY_CREDENTIALS, bundle.getString("ROOTPASS") );
env.put( Context.SECURITY_CREDENTIALS,password);
//LDAP connection pooling is implemented
env.put("com.sun.jndi.ldap.connect.pool", "true");
ctx = new InitialDirContext(env);
StringBuffer uidBuffer = new StringBuffer();
//pass the logged in username from portal to query and fetch the attributes from LDAP Server
uidBuffer.append("uid="+LoggedInUser);
//System.out.println(LoggedInUser);
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
answers = ctx.search("",uidBuffer.toString(), ctls);
while(answers.hasMore()) {
SearchResult sr = (SearchResult)answers.next();
Attributes attrs = sr.getAttributes();
//get all the required values
Attribute givenname=attrs.get("givenname");
Attribute middlename = attrs.get("middlename");
Attribute sn = attrs.get("sn");
//format all the fetched attributes to get the exact values & add all the formatted values to the array list and
return
if(givenname !=null)
{
formattedGivenname=formatGivenname(givenname.toString());
list.add(formattedGivenname);
}else
{
formattedGivenname=" ";
list.add("");
}
if(middlename !=null)
{
formattedMiddlename=formatMiddlename(middlename.toString());
list.add(formattedMiddlename);
}else
{
formattedMiddlename=" ";
list.add("");
}
if(sn !=null)
{
formattedSn=formatSn(sn.toString());
list.add(formattedSn);
}else
{
formattedSn=" ";
list.add("");
}
}
}catch (NamingException ne)
{
System.err.println(ne.toString());
}
finally
{
if(answers !=null)
{
answers.close();
}
if(ctx != null)
{
ctx.close();
}
}
Although in theory the connection pooling was working, it was still creating a lot of connections.
Then, upon closing all NamingEnumerations (Marked in Red), we finally got the perfect results. 100s of requests a minute & only around 10–15 LDAP connections open at any one time.

LDAP API Programming Best Practices
I. When creating contexts, share the factory to use pooling
II. Make sure you close everything. If it has a close(), use it.