Monday, May 18, 2015

WebLogic Server and OpenLDAP. Using Dynamic groups

Dynamic groups in an LDAP are groups which contain a query to specify its members instead of specifying every member separately. Efficient usage of dynamic groups makes user maintenance a lot easier. Dynamic groups are implemented differently in different LDAP server implementations. Weblogic Server can be configured to use dynamic groups in order to fetch users for a specific group. In this blog I will describe how dynamic groups can be created in OpenLDAP and used in Weblogic Server.

In this example I use two users. smeetsm the developer and doej the operator. As shown in the image below, there are many servers which follow a similar access pattern for operators and developers. We are considering a case here where users do not use a shared account (e.g. weblogic) to login to different systems. This is for trace-ability and security purposes a better practice than when everyone uses the same shared user. See http://otechmag.com/magazine/2015/spring/maarten-smeets.html for a more thorough explanation on why you would want this.


A small note though. I'm a developer and this is not my main area of expertise. I have not implemented this specific pattern in any large scale organization.

Why dynamic groups?

In the group definition you can specify a query which determines members based on specific attribute values of users (e.g. privileges). What can you achieve with dynamic groups? You can provide an abstraction between users and groups which allows management of just user attributes to grant privileges. Groups which are usually per server, do not require as much changing this way. Since usually there are many servers (see example above) this saves a lot of time.

For example, you can use the departmentNumber attribute to differentiate what developers and operators can do on different machines. For readability I have misused the employeeType here since it allows string content. In the below image there are two users. smeetsm who is a developer and doej who is an operator. I have defined roles per server in the LDAP. The Monitor role on Server1 has smeetsm and doej as members because the memberURL query selects persons who have employeeType Developer or Operator. On Server1 only doej is Administrator and not smeetsm. This can for example be considered an acceptance test environment. On Server2 both are Administrator and Monitor. This can be considered a development environment. When smeetsm leaves and goes to work somewhere else, I just have to remove the Developer employeeType attribute at the user level and he won't be able to access Server1 and Server2 anymore. So there is no problem anymore with forgetting which server which person has access to.


OpenLDAP configuration

Install

First download OpenLDAP from http://sourceforge.net/projects/openldapwindows.

In order to reproduce the configuration I have used do the following;

Download the configuration and LDAP export: here

Put the slapd.conf in <OpenLDAP INSTALLDIR>\etc\openldap

Check if the password specified for the administrator works. Not sure if the seed is installation dependent. You can generate a new password by going to  <OpenLDAP INSTALLDIR>\bin and execute slappasswd -h {SSHA}

Start OpenLDAP by executing  <OpenLDAP INSTALLDIR>\libexec\StartLDAP.cmd (or the shortcut in your startmenu)

Put the export.ldif in <OpenLDAP INSTALLDIR>\bin
Open a command-prompt and go to the <OpenLDAP INSTALLDIR>\bin

Execute
ldapadd.exe -f export.ldif -xv -D "cn=Manager,dc=smeetsm,dc=amis,dc=nl" -w Welcome01

Now you can browse your OpenLDAP server using for example Apache Directory Studio. In my case I could use the following connection data (I used Apache Directory Studio to connect);

BindDN or user: cn=Manager,dc=smeetsm,dc=amis,dc=nl
Password: Welcome01


The member field gets generated automatically (dynlist configuration in slapd.conf). This happens however after a search is performed. WebLogic can't find this person if defined as a static group (I've enabled authentication debugging to see this in the log, Server, Debug, weblogic.security.Atn);

<search("ou=Server1, ou=groups, dc=smeetsm, dc=amis, dc=nl", "(&(member=cn=doej,ou=people,dc=smeetsm,dc=amis,dc=nl)(objectclass=groupofurls))", base DN & below)> 
<getConnection return conn:LDAPConnection {ldaps://localhost:389 ldapVersion:3 bindDN:"cn=Manager,dc=smeetsm,dc=amis,dc=nl"}> 
<Result has more elements: false> 

Unless you want to invest time in getting to know your specific LDAP server in order to make the dynamic groups transparent to the client (so you can access them in a similar way as static groups), you're probably better of fixing this in WebLogic Server using dynamic groups (at least for development purposes). You can try however to let OpenLDAP produce memberof entries at the user level. This will perform better as WebLogic does not need to analyse all groups for MemberURL entries to determine in which group the user is present.

There are several tutorials available online for this (for example http://www.schenkels.nl/2013/03/how-to-setup-openldap-with-memberof-overlay-ubuntu-12-04/). Most however use OpenLDAPs online configuration (olc) and not slapd.conf. olc is the recommended way of configuring OpenLDAP and in most distributions the default. However not in the one I was using.

From slapd.conf to olc (optional)

This part is optional. It might help if you're planning to take a dive into the depths of OpenLDAP (don't forget the oxygen... I mean coffee). You can convert your slapd.conf to an online configuration as shown below.

See http://www.zytrax.com/books/ldap/ch6/slapd-config.html. I had some problems with creation of the slapd.d directory so I first create another directory called 't' and rename it. It is a good idea to also rename the slapd.conf in order to make sure this configuration file is not used anymore.

cd <OpenLDAP INSTALLDIR>\etc
mkdir t
<OpenLDAP INSTALLDIR>\sbin\slaptest.exe -f openldap\slapd.conf -F t
move openldap\slapd.d
move openldap\slapd.conf openldap\slapd.conf.bak

Update the last line of <OpenLDAP INSTALLDIR>\libexec\StartLDAP.cmd to use the newly created directory for its configuration
slapd.exe -d -1 -h "ldap://%FQDN%/ ldaps://%FQDN%/" -F ..\etc\openldap\slapd.d

Create a user which can access cn=config. Update <OpenLDAP INSTALLDIR>\etc\openldap\slapd.d\cn=config\olcDatabase={0}config.ldif (from: http://serverfault.com/questions/514870/how-do-i-authenticate-with-ldap-via-the-command-line)

Add between
olcMonitoring: FALSE
and
structuralObjectClass: olcDatabaseConfig
the following lines. Use the same password as in the previously used slapd.conf (created with slappasswd -h {SSHA})

olcRootDN: cn=admin,cn=config
olcRootPW: {SSHA}2HdAW3UmR5uK4zXOVwxO01E38oYanHUa

Now you can use a graphical LDAP client to browse cn=config. Authenticate using cn=admin,cn=config and use cn=config as Base DN. This makes browsing and editing configuration easier.


To add a configuration file you can do the following for example;

<OpenLDAP INSTALLDIR>\bin>ldapadd.exe -f your_file.ldif -xv -D "cn=admin,cn=config" -w Welcome01

Here I'll leave you to figure out the rest for yourself to get the memberof attribute working. Good luck! (as told before, you don't really need this unless performance becomes a bottleneck)

WebLogic configuration

In the WebLogic Console, Security Realms, myrealm, Providers, New, OpenLDAPAuthenticator.

Use the following properties;
Common: Control Flag. SUFFICIENT. Also set the control flag for the DefaultAuthenticator to SUFFICIENT.

Provider specific

Connection

  • Host: localhost
  • Port: 389
  • Principle: cn=Manager,dc=smeetsm,dc=amis,dc=nl
  • Credential: Welcome01

Users

  • User Base DN: ou=people, dc=smeetsm, dc=amis, dc=nl
  • All users Filter:
  • User from name filter: (&(cn=%u)(objectclass=inetOrgPerson))
  • User Search Scope: Subtree
  • User name attribute: cn
  • User object class: person
  • Use Retrieved User Name as Principal: (leave unchecked)

Groups

  • Group Base DN: ou=Server1, ou=groups, dc=smeetsm, dc=amis, dc=nl
  • All groups filter:
  • Group from name filter: (&(cn=%g)(|(objectclass=groupofnames)(objectclass=groupofurls)))
  • Group search scope: Subtree
  • Group membership searching: unlimited
  • Max group membership search level: 0

Static groups

  • Static Group Name Attribute: cn
  • Static Group Object Class: groupofnames
  • Static Member DN Attribute: member
  • Static Group DNs from Member DN Filter: (&(member=%M)(objectclass=groupofnames))

Dynamic groups

  • Dynamic Group Name Attribute: cn
  • Dynamic Group Object Class: groupofurls
  • Dynamic Member URL Attribute: memberurl
  • User Dynamic Group DN Attribute:

GUID Attribute: entryuuid

Points of interest

Notice that the group from name filter specifies two classes. The class for the static groups and the class for the dynamic groups.

Notice User Dynamic Group DN Attribute is empty. If you can enable generation of the memberof attribute in your LDAP server, you can use that.

Notice that the Group Base DN specifies the server. For Server2 I would use Server2 instead of Server1.

You can use static and dynamic groups together and also nest them. In the below image, Test3 is a groupofnames with smeetsm as static member. Monitor is a dynamic group.


Be careful though with the performance. It might not be necessary to search entire subtrees to unlimited depth.

Result

After the above configuration is done, can login with user smeetsm on Server1 into the WebLogic Console and get the Monitor role while on Server2 with the same username, you get the Administrator role.


If I change the employeeType of smeetsm to operator, I get the Administrator role on Server1. If I remove the attribute, I cannot access any system. User management can easily be done this way on user level with very little maintenance needed on group level (where there usually are many servers) unless for example the purpose of an environment changes. Then the query to obtain users needs changing.

I could not get the memberof attribute working in my OpenLDAP installation. Luckily for a development environment you don't need this but if you plan on using a similar pattern on a larger scale, you can gain performance by letting the LDAP server generate these attributes in order to allow clients (such as WebLogic Server) to get quick insight into user group memberships.

Please mind that in order for the FMW components (from the IdentityService to WebCenterContent) to use dynamic groups you need to enable the DynamicGroups plugin in the LibOVD configuration. See: http://www.ateam-oracle.com/oracle-webcenter-and-dynamic-groups-from-an-external-ldap-server-part-2-of-2/ in order to allow usage of the dynamic groups.

No comments:

Post a Comment