« Workshop 10.1, Maps, GeoRSS, REST and more | Main | Changing WebLogic Annotations on the Fly (more detail) »

Using OpenLDAP with WebLogic Server

This was originally posted on my dev2dev blog August 12th, 2007.

A customer I was working with this week had some difficulty using Active Directory in conjunction with WebLogic Server Security.  I've always used the Embedded LDAP server that ships with WLS as my user and group store since most of my work is just demos and prototypes, but I thought this would be an excellent opportunity to see what it is like to configure an external LDAP provider.  Since I don't have easy access to Active Directory, I decided to use OpenLDAP.  I am an LDAP newbie and was surprised at the lack of results that I received searching on google for my LDAP 101, but I was able to piece enough information together from wikipedia and other articles to get me going.

Install and configure OpenLDAP

OpenLDAP is typically used on *nix systems, but my laptop runs Windows XP.  I was able to find someone that makes a Windows Distribution and I retrieved version 2.2.29.  It's very straight forward to download and install it as a Windows Service.  Similar to Apache's httpd.conf file, the sldapd.conf in the base directory is the master configuration file.

I had to change two things about my file.  At the top, I added support for additional schemas based on advice on an email thread.  It seems like it is very common to use the inetOrgPerson object class based off of my limited shoulder surfing at customer sites, so I added support for that and one other one named cosine.

#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
ucdata-path    ./ucdata
include        ./schema/core.schema
include        ./schema/cosine.schema
include        ./schema/inetorgperson.schema

At the very bottom of the sldapd.conf file, you should see a few other things to configure.

database    bdb
#suffix        "dc=my-domain,dc=com"
suffix        "dc=bea,dc=com"
rootdn        "cn=Manager,dc=bea,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw        secret
# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory    ./data
# Indices to maintain
index    objectClass    eq
So what this section says is that OpenLDAP will use BDB as it's database and store the information in the data directory.  These are defaults.  This was helpful to know as I messed up my database a few times playing around with various settings and could always just stop OpenLDAP, delete the data directory and start OpenLDAP to start from a clean slate.  The default suffix for entries typically follows the domain name conventions, so in this case I used bea.com where the DC stands for Domain Component.  This site has additional definitions for the other LDAP abbreviations like CN (Common Name) and SN (Sir Name).  The default for the root user name is Manager and the password defaults to secret.  Of course in a real production setting you would want to encrypt this password, but for my demo purposes, this works fine.  Now I started the Windows Service, executed a netstat command and observed that I was now listening on the LDAP port of 389 and was up and running.

Add Users and Groups

When you first start OpenLDAP, there is no user/group structure provided, you have to add those entries yourself.  LDAP uses the LDIF format to import and export entries into LDAP.    I was able to find some examples and modify them to have a user/group structure that worked for my example purposes.  Like I said, I'm an LDAP newbie, so do not consider this a recommended structure for your enterprise, but it worked for me to store both users and groups in a very basic way.  I'll show you a tool that you can use later to do this visually, but it's helpful to know what's going on under the covers so you understand what the tool is doing.

dn: dc=bea,dc=com
dc: bea
objectClass: top
objectClass: domain

dn: ou=people,dc=bea,dc=com
ou: people
objectClass: top
objectClass: organizationalUnit

dn:cn=jbayer,ou=people,dc=bea,dc=com
objectClass:inetOrgPerson
cn:jbayer
sn:Bayer
uid:jbayer
userPassword:weblogic

dn: ou=groups,dc=bea,dc=com
ou: groups
objectClass: top
objectClass: organizationalUnit

dn: cn=groupA,ou=groups,dc=bea,dc=com
objectClass: top
objectClass: groupOfNames
cn: groupA
member: cn=jbayer,ou=people,dc=bea,dc=com


Above are the contents of a file I called base.ldif.  Here I define two organization units, people and groups.  Under people I have a user single user named jbayer and under groups I have one group named groupA, of which jbayer is a member.  To import this into OpenLDAP, I just use the ldapadd command as shown below.
 
C:\Program Files\OpenLDAP>ldapadd.exe -f base.ldif -xv -D "cn=Manager,dc=bea,dc=com" -w secret
ldap_initialize( <DEFAULT> )
add dc:
        bea
add objectClass:
        top
        domain
adding new entry "dc=bea,dc=com"
modify complete

add ou:
people
add objectClass:
top
organizationalUnit
adding new entry "ou=people,dc=bea,dc=com"
modify complete

add objectClass:
inetOrgPerson
add cn:
jbayer
add sn:
Bayer
add uid:
jbayer
add userPassword:
weblogic
adding new entry "cn=jbayer,ou=people,dc=bea,dc=com"
modify complete

add ou:
groups
add objectClass:
top
organizationalUnit
adding new entry "ou=groups,dc=bea,dc=com"
modify complete

add objectClass:
top
groupOfNames
add cn:
groupA
add member:
cn=jbayer,ou=people,dc=bea,dc=com
adding new entry "cn=groupA,ou=groups,dc=bea,dc=com"


Using an LDAP Browser

Since doing all this command line stuff isn't very visual, you can also use this Java LDAP Browser to view/modify OpenLDAP entries and to validate that your entries got imported correctly.  Dowload the tool and use connection settings similar to mine shown below (click the thumbnail to get a larger view), which should result in you being able to connect and browse the tree.  You can also use this tool to add and edit entries, but I won't cover that here.  Edocs also has instructions on how you can use this same tool to browse the Embedded LDAP server that comes with WLS.
 
openLdapConfig ldapBrowser [3]

Configure WebLogic Server

By default, WebLogic Server uses an security realm called myrealm that uses the Embedded LDAP server configured with the Default Authenticator.  In order to add OpenLDAP as a source, you have to configure an additional Authentication Provider to the realm.  Here are the steps for configuring WLS 10, although the steps are similar with other WLS versions.

  1. Login to the WLS console - my example servier is at http://localhost:7001/console  with user weblogic and password weblogic
  2. Browse to Security Realms->myrealm
  3. Click on the Providers tab
  4. Browse to the Authentication section
  5. Click the Lock and Edit button
  6. Click the new button and select OpenLDAPAuthenticator and give it a name, I chose openLDAPAuthenticator
  7. Click on the newly created Authenticator and select the Provider Specific tab
  8. I changed the following settings from the provider specific defaults based on the values I loaded in the ldif file shown earlier:

Group Base DN:  ou=groups,dc=bea,dc=com
Static Group Object Class:  groupOfNames
User Base DN:  ou=people,dc=bea,dc=com
User Object Class:  inetOrgPerson
Principal:  cn=Manager,dc=bea,dc=com
Host:  localhost
Credential:  secret
Confirm Credential:  secret
Static Group DNs from Member DN Filter:  (&(member=%M)(objectclass=groupOfNames))
User From Name Filter:  (&(cn=%u)(objectclass=inetOrgPerson))
Group From Name Filter:  (&(cn=%g)(objectclass=groupOfNames))

One Major Gotcha - Setting the Default Authenticator to something other than "Required"

Now you can save and Active the session.  WebLogic Server needs to be restarted for changes in the Authenticator to take effect, but before you restart there is one other change we have to make.  Authenticators have an attribute named Control Flag.  The value is either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL.  See the help in the console for detailed explanation of these values.  The Default Authenticator has a default value of REQUIRED that should be changed to either SUFFICIENT or OPTIONAL in order for users that are only OpenLDAP to be able to login to with the WebLogic Security Framework without also having to be in Embedded LDAP.

After restarting, log back into the console, browse to your realm and select the Users and Groups tab.  You should see the user you added.  If you select a user from OpenLDAP you should be able to change their password as well as see their group membership if everything is configured properly.
 
jbayer 

Secure a web application

You can try it out by creating a simple web app with a security-constraint element in web.xml entry as follows that defines a role named SecuredUser and uses it to protect all resources in the web app:
<security-constraint>
 <web-resource-collection>
  <web-resource-name>restricted</web-resource-name>
  <url-pattern>/*</url-pattern>
 </web-resource-collection>
 <auth-constraint>
  <role-name>SecuredUser</role-name>
 </auth-constraint>
</security-constraint>
<login-config>
 <auth-method>BASIC</auth-method>
 <realm-name>SecuredRealm</realm-name>
</login-config>
<security-role>
 <role-name>SecuredUser</role-name>
</security-role>
Then in your weblogic.xml define element to add an security-role-assignment element to a specific user.
<wls:security-role-assignment>
     <wls:role-name>SecuredUser</wls:role-name>
     <wls:principal-name>jbayer</wls:principal-name>
</wls:security-role-assignment>
If you would rather use LDAP groups to specify the role assignment, which is much more likely to be the case, then you would use a section like this in your weblogic.xml.
<wls:security-role-assignment>
     <wls:role-name>SecuredUser</wls:role-name>
     <wls:externally-defined/>
</wls:security-role-assignment>

In this case, instead of explicitly naming all of the users you want in that role in each web applications deployment descriptors which is not a very good practice for an enterprise, the role SecuredUser will be assumed to be a Global Role defined in your realm's Roles and Policies -> Global Roles.  In the console, you can assign the Global Role SecuredUser to all users with membership in groupA for example.

What if you want to find out additional LDAP attributes other than users and groups and use them in your applications?  In a subsequent post I plan on showing how to use an LDAP control to do that or use the Unified User Profile feature of WebLogic Portal to automatically stuff those values in the user profile.

Comments (5)

Víctor Glez.:


I followed the steps in the tutorial.
I have SQL Authenticator(Default Authenticator) as OPTIONAL and the new OpenLDAP Authenticator as REQUIRED

Now I have the problem that I can not sign with the new user (jbayer) in WLS



weblogic.security.SecurityInitializationException: User jbayer is not permitted to boot the server; The server policy may have changed in such a way that the user is no longer able to boot the server.Reboot the server with the administrative user account or contact the system administrator to update the server policy definitions.
at weblogic.security.service.CommonSecurityServiceManagerDelegateImpl.doBootAuthorization(Unknown Source)
at weblogic.security.service.CommonSecurityServiceManagerDelegateImpl.initialize(Unknown Source)
at weblogic.security.service.SecurityServiceManager.initialize(Unknown Source)
at weblogic.security.SecurityService.start(SecurityService.java:141)
at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)
Truncated. see log file for complete stacktrace

What are the groups that should belong to the user to log in as administrator WLS?
Is this possible?

Thank you

Victor, only users in certain roles such as Admin or Operator can start the server, and to map to those roles, you need to be in certain Groups in the Authentication Provider. This is documented here:
http://download.oracle.com/docs/cd/E12839_01/wls/docs103/secwlres/secroles.html#wp1221588

Did you put your jbayer user in the Administrators group or modify your Admin role to include jbayer?

Javier:

Hi James

I have the same problem, but how can i modify the roles if i can't start the server?? I had only a administrator and now i can't start because i have this problem

Javier,

Try to revert to the embedded LDAP (Default Authenticator) user that was in your server's boot.properties file at the time the domain was created. By default this is named "weblogic" unless you change it. Then you should be able to start the server and make any adjustments to the roles, etc with the users from the Open LDAP Authenticator.

I'd been fiddling with the LDAP settings all day trying to get this working . I hadn't realised that the gotcha with the Default Authenticator had been causing the problems all along and that the settings I'd been using were fine.

Thanks very much for posting this article, saved me a sleepless night!

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

james_bayer.jpg

I am a Senior Sales Consultant covering enterprise customers in and around the Chicago area focusing on middleware and internet technologies. My career began as a Java consultant and architect where I experienced the technology shift toward SOA. I enjoy helping customers solve business problems by applying Oracle technology solutions.

About This Entry

This page contains a single entry from the blog posted on August 12, 2007 7:56 PM.

The previous post in this blog was Workshop 10.1, Maps, GeoRSS, REST and more.

The next post in this blog is Changing WebLogic Annotations on the Fly (more detail).

Many more can be found on the main index page or by looking through the archives.

Top Tags

Powered by
Movable Type and Oracle