Packaged LDAP Authentication [SOLVED]

Permalink 16 users found helpful
Been working on this for a little while.

Though this has worked flawlessly for me, I would hesitate implementation in a production environment at this point.

When installed, the original login page is deleted and replaced. However, upon uninstall, the original settings are restored. This is a less than desirable, but makes for a seamless implementation of support for LDAP authentication.

Until we get native support for third party authentication protocols, this has been the only method I've found that will work, aside from modifying core files.

When you try to login, c5 will ask the LDAP host to authenticate the user's credentials. If the user is not already in the c5 database, a new user profile is create with the provided username and password.

As a fail-over, if the LDAP host is unreachable, the c5 database will be used to authenticate the user by using the last working password authenticated by the LDAP host (it's updated every login).

No users will be deleted upon install or uninstall, however, if a user with the same username exists, their password WILL be overwritten by the last password authenticated by the LDAP host.

Quick shout-out of thanks goes out to Andrew.

Questions, comments and requests are welcomed!

At this point I would not recommend using this package, however, I am leaving it here as a reference to anyone that wants to see how it works.

The authentication method works well, but the way the Login page gets replaced when the package is installed is quite intrusive to the c5 core and can make things unstable in certain environments.

A package was funded and entitled an MIT license that provides LDAP Authentication support. Thanks goes to Cascadia Behavioral Health Care for the project funding and the allowance of an MIT license.

At some point I'll get this up on the MarketPlace, but for now...

[EDIT 3 - Dec. 30th, 2012]
Latest version is now compatible with versions and below.

[EDIT 4 - Sept. 25, 2014]
Reinhilde Kircher (strawberry) has been kind enough to update the code to work with nested groups. The attached file name is

It should be noted that I have not tested it in any capacity. However, to get it to work, you'll need to replace the ldap_authenticator.php file in the "helper" folder with Reinhilde's new version.

See attached.

2 Attachments

View Replies:
keithdmoore replied on at Permalink Reply
Talk about just in time...I am considering Concrete5 for a potential client and LDAP integration is a must have. Looks like Concrete5 may still be a contender. Really liking it so far.
ijessup replied on at Permalink Reply
Well, like I said: it's working, but it ain't polished.

I haven't had time to work on it in the past week, but I'll eventually get it Market worthy.

The most difficult part is understanding the LDAP Base Query. I'd like to integrate a way to easily generate one for you, but I've got a huge-mongous project on my hands at the moment, and just needed some quick and dirty LDAP authentication for c5 that's easily portable to other instances.

For now you'll need to use something like: CN=YourGroup,OU=Users,DC=YourDomain,DC=com
keithdmoore replied on at Permalink Reply
What you have done should be good enough. It seems pretty standard to have to supply that information anyway. I will most likely be testing it out in a few weeks. Are you planning on selling this or giving it away?
ijessup replied on at Permalink Reply
End product will likely be put for sale in the MarketPlace. But I know people have been hungry for at least some basic support, so I released this to get people on their feet. I didn't add a license to the zip file, but consider it MIT -> "Do whatever you want with it, and don't sue me if you break something when using it."

I'm actually still waiting for the next c5 core to support 3rd party authentication. Then I'll write a 'real' package.
keithdmoore replied on at Permalink Reply
What 3rd party authentication products are you refering to? This looks rather interesting:
ijessup replied on at Permalink Reply
By that I meant more native support for developers to write authentication add-ons to use things like LDAP, Facebook, Twitter... etc.

Packages exist now, but they are hacked together - so to speak. However, from what I understand, there are plans to make packaging authentication add-ons much easier and with tighter integration.
keithdmoore replied on at Permalink Reply
I see. I have seen a site that uses a user's facebook account for logging in. Pretty cool. I think it would be good to have more options in this space. The LDAP integration is a "must-have" for my current client. If I can't get something to work then we will have to select a different product. The only other client complaint is the lack of more core and free add-ons. Hopefully this will change as time goes on.
ijessup replied on at Permalink Reply
Sure, free stuff is nice, but when you start trying to integrate solution built for Linux environments with Microsoft Networks... prepare to have your wallet violated.

You'll see free add-ons of this nature, but likely cripple-ware compared to versions you have to pay for. And you'll only see those because the select few developers feel they have a moral obligation to give back to the community. Open source communities start failing when people just take, take, take and don't give back.

Case and point, what I released. It works, but you need to know how to work with LDAP in order to get it to work right. Where as a paid version would make it so my 14 year old brother could manage it.

There are a ton of c5 fanboys here that would love to see everyone move this direction (myself included). But it's hard to work for free, ya know?

I mean, I assume you get paid for your work, right? And I'm sure it's been a task to find a CMS worth using with the features you want/need. Cross platform development is painful. Compensation is necessary.
keithdmoore replied on at Permalink Reply
I agree with your points. I certainly get paid to work for my clients. If I work on something for them and get paid for it I will certainly give it back for free. I don't expect to get paid twice(or more). However, if I worked quite a bit on something on my own and thought it was of high quality then I would like some small compensation. Which is why I like the whole marketplace implementation.
SpencerC replied on at Permalink Reply
I like the fact that for my clients I can say that add-ons are tested by the team before being posted on the Marketplace. Some sense of security and that's worth it. Plus if developers are being paid to create add-ons they are more likely to create a quality product and keep it updated.

Now, about the LDAP integration. Arrrgggh!

keithdmoore replied on at Permalink Reply
Good points. I agree. So are you using the LDAP plug-in? I havent had a chance to yet.
SpencerC replied on at Permalink Reply
Not at this point. Actually, my client's IT dept is going to take care of the integration and we are not sure how we will do it at this point. I'm in research phase to find some options.

rjlowecsn replied on at Permalink Reply
I'm currently testing this on one of our development servers, and it seems to be working great. One thing I'm hoping to do, if it's not included in a later version, is to use the users AD security groups and add/verify against those as well. We would like to tie the user's C5 privs to their "memeberof" LDAP groups.

I've been experimenting with it and it does look a bit hairy, but doable. If I come up with something better than an cursory experiment I'll try to remember to post my findings.

Any thoughts on this?
ijessup replied on at Permalink Reply
If you look at the ~/packages/ldap_login/controllers/ldap_login.php file @line 173, you can see that the server is actually queried and you can user the returned array to trigger conditionals that either insert people into groups, or just define $_SESSION variables.
rjlowecsn replied on at Permalink Reply
Maybe I'm just reading the code wrong, but that section appears to be handling error cases, up around line 138 you run into things like: if ($u->isError()) {
switch($u->getError()) {
etc. etc.

I need to be hitting LDAP on every login, successful or not, in order to check the user's AD credentials/groups to see if they've changed since the last login. The try statement at line 157 seems to me that if the user exists, then move on; and the LDAP query specified in the else case started at line 166 is never executed.

Or, as I said earlier, I'm just reading the code wrong, which could easily be the case. I'm much more comfortable with procedural/function code than OOP code.
haan replied on at Permalink Reply
Actually, the way the script is set up is the following:

1. In line 137, the script first tries to authenticate the user using local information from the MySQL database (concrete5 userbase). If that authentication is successful, the script moves on and never queries LDAP.

2. If the login in line 137 is unsuccessful, the script first checks the cause of the failure: non validated user or whether he used an invalid email address. If all this fails, we are in a situation where the user specified an unknown login name and password and only then are we querying LDAP.

3. The try/catch from line 157 to line 177 is the LDAP connection and the lines 178 - 189 are the error handling of the LDAP connection and authentication.

If you want to hit LDAP on every login (which might be dangerous since the LDAP server might be down or unresponsive), you need to modify the script and remove the local login in line 137 and only keep that section using the LDAP authentication.
rjlowecsn replied on at Permalink Reply
That's what I thought. I'd rather have it work in reverse, so to speak:

1) Try to verify user/security groups first via LDAP (if successful, check to see if LDAP group membership has changed since last time, and update, but don't prevent login, just update the local MySQL groups & usergroups tables). If this is a new user, add their LDAP credentials to the local MySQL tables: users, groups, usergroups.

2) If LDAP connection fails, just check the local MySQL db for the user and their group privs, and login in with those historical credentials.

3)If THAT fails, fail the login completely and notify user that they are new and will need to wait for LDAP verification in order to login (I would think this would be a very rare occurance since it would only happen for new users and LDAP would have to fail).

So with that, I know I will need to re-code this portion of the app. Thanks for the heads-up!
rjlowecsn replied on at Permalink Reply
Hmmm, after looking at the code for awhile, it almost doesn't seem like the do_login function is even getting executed every time someone logs in? Only when a new user/password is encountered.

Am I reading that right? I only see do_login() getting called from the change_password() function, which itself is only called from the forgot_password() function. And I think, but I'm not sure, that forgot_password() is only getting called when an unrecognized User/PW is encountered by the openID stuff. ??? I think maybe I'm missing something here?
haan replied on at Permalink Reply
The login form action is "/index.php/login/do_login/" which in Concrete5 means the "do_login" function of the login page is executed. This is handled automatically by Concrete5 which is why you won't see many calls to that function in the code itself.
RebeccaSt replied on at Permalink Reply
Was looking for an LDAP integration with C5 and came across your addon. I installed the addon and configured the LDAP settings. But now when I try to login I receive the following error:

Fatal error: Cannot redeclare class PageNotFoundController in D:\Inetpub\\concrete\controllers\page_not_found.php on line 12

Any help would be much appreciated!
ijessup replied on at Permalink Reply
Hmmm... the current package actually removes the original Login page. Given the lack of 3rd party authentication support, this is necessary, but unfortunate.

I honestly haven't looked at the package in a while so I'm not sure what could be causing the issue.

Something is initialising the PageNotFound class from my code, and then it gets initialised again by something else... or vise versa.
haan replied on at Permalink Reply
First of all, let me thank you for all the work that you put into developing this plugin. It was a very helpful starting point and allowed me to implement a fully working LDAP authentication.

As I had quite a few problems with your package, i'd like to share a few points that I feel are important to mention:

1. I installed your plugin on an Ubuntu server with that MySQL distribution that comes along Ubuntu. The default behavior of such an installation is that table names are case-sensitive. This is problematic since you use the table "config" quite a lot in your queries even though the correct name would be "Config". I had to change this before I could even get your package to work.

2. In the file ldap_login/controllers/ldap_login on line 186, where you implement your custom error-reporting messages, you access the field "msg" of object $e. This field was empty for me and the correct method would be to use $e->getMessage()

3. In the same file in line 174, you use the static function UserInfo::register to add a new user. Since I'm not very familiar with the concrete5 API, I looked it up but couldn't find the register method in the API ( Maybe this method is deprecated (?) and I replaced it with UserInfo::add() as mentioned in the API.

4. Finally, I stumbled upon a huge problem: in our LDAP, we have our users distributed over several organizational units (OU). If I specify a OU in the Base Query such as: "OU=xxx,DC=yyy,DC=zzz" I can authenticate with any user and retrieve information from users in that OU. This is however not what I wanted since I need all the users from all the OU. Leaving out the "OU=xxx" part from the Base query, I could authenticate with any user but not retrieve any user information. Even after setting the LDAP_OPT_REFERRALS to false, the behavior was the same. I eventually concluded that it was a problem with adodb and after i completely replaced adodb with native php5-ldap functions, it worked flawlessly!

In the end, I used these two lines to find user information from any user regardless his OU:

$filter = "(&(objectCategory=person)(sAMAccountName=" . $this->post('uName'). "))";
$result = ldap_search($ds, $ladp_config['LDAP_BASE'], $filter);

Thanks for your help and keep up the good work!
rjlowecsn replied on at Permalink Reply
Hi Haan,

(Thanks for the info to my query above, btw)

In my case, for your issue #1, on a Win2K8 WAMP stack, the MySQL tables were all lowercase. Perhaps that check needs to account for both upper/lower-case possibilities.

Can't help with #2 or #3 since I did not encounter those issues.

For issue #4, it took me awhile to build a working Base Query as well. That is until I found a neat little trick. If you're logged into the AD Domain on a windows box, you can go to the cmd window and type the command gpresult and you will get all of the AD info for the logged in user. The key part being, if you scroll down to the USER SETTINGS portion, you will see the CN, OU, DC info for that user. In our setting, and perhaps yours, above the specific OU, there was a generic OU that I could use to build my Base Query.

I hope this info is helpful to you and to others wrestling with building a working Base Query.
matchesfashion replied on at Permalink Reply
I have been trying to integrate this for my companies Intranet but I am having no luck sadly. When ever I log in using an account from my active directory all I get is a white screen.

Any ideas on why I am seeing this would me most appreciative
SpencerC replied on at Permalink Reply
I'd recommend hiring Isaac.
ijessup replied on at Permalink Reply
It's likely to do with the poor method I originally used to replace the Login page. I have since altered this method to be less intrusive.

At this point, I would not recommend using the previously posted package.
dimunation replied on at Permalink Reply
I'm planning to implement an LDAP login solution using your code as the basis. Given your comments above, is there an updated package available? I'd happy purchase this directly or through the market if so.
dimunation replied on at Permalink Reply
Excellent - Thank you again!

I'll be implementing this in the next day or two, and will report any bugs or feedback from the project.

Let me know when you publish this to the marketplace - I'll happily be your first customer...! I think you'll find a good market for this as an add-on, and would expect that those who would be implementing this type of functionality would be happy to pay for a packaged solution.
ijessup replied on at Permalink Reply
There was a report that Safari users appeared to be logged in even after logging out, but the issue couldn't be recreated. So keep an eye out for that, but otherwise no other reports.

It's also important to note that if there is an account in LDAP that has the same sAMAccount name as the c5 admin account, the password will update when you run the LDAP query job. I should fix this, but haven't had a chance. However, the account password does not update (like all the other accounts do) when you log in.
bjazmoore replied on at Permalink Reply
Is the attached file the newest version of your LDAP package? I found this by accident and I am extremely excited to try it out.
ijessup replied on at Permalink Reply
The file attached to the original post is the newest version.
dimunation replied on at Permalink Reply
A few notes thus far.

- Able to properly configure a base query and connect to the ldap server.

- For some reason, the config value for LDAP_FILTER didn't make it in to the database during installation. Adding it manually fixed the issue. At first glance, I can't see anything that would prohibit that config value from being added to the database.

- The LDAP poll job appears to check for matches in the active directory, and then assign a random password to each if a match is found. Is this the desired functionality?

if(is_array($ldap['return'])) foreach($ldap['return'] as $user) {
         if(!$user['mail']) $user['mail'] = $user['sAMAccountName'].'@'.Config::get('LDAP_DOMAIN_NAME');
         Loader::helper('ldap_authenticator', 'ldap_auth')->register($user, mt_rand());
ijessup replied on at Permalink Reply
Not sure about the LDAP_FILTER issue.

Yes, this is the desired effect. When a user signs in with credentials validated by the LDAP server, the user's password will get updated.

A potential issue that that if there is a user in the LDAP user base that has the same username as the c5 super user (User with ID 1) it will over write make SU's password random. By default the SU doesn't get validated by the LDAP server just in case something goes wrong with the server and you need some kind of back door.
dimunation replied on at Permalink Reply
Got it - so the point of the random password is the expectation that it will be overwritten upon logging in via LDAP.

The only problem i could foresee is if the LDAP poll job runs successfully, then at a subsequent point the LDAP server becomes unavailable. The password will no longer match the previous C5 password, and the LDAP server won't be able to authenticate the user.
ijessup replied on at Permalink Reply
That is correct. Well found.

I've been meaning to fix the SU's password issue. I could hit two birds with one stone by just telling it to ignore existing users.

Unless you want to make the changes yourself, expect an update in the next week or so.
dimunation replied on at Permalink Reply
An update -

This has been running on a production server for about a week now. The only other change I needed to make was to overwrite the controller for the login page with the contents of the ldap_login controller. When the login page was loaded directly, everything worked properly. For some reason, when a page presented the login dialog (such as requesting the dashboard while not logged in), the request never made it to the ldap_login, and instead attempted to authenticate using the C5 user database. There have been some other customizations to this installation in the past, so this might not occur on a fresh install.

After that change, I've seen no problems whatsoever. Both the active directory and C5 user database on this server are large (1000+), and the site sees heavy traffic.
ijessup replied on at Permalink Reply
That's odd. There is a helper that should automatically forward the guest to the "ldap_login" page anytime they are sent to the "login" page. This is done on the controller level too, and the script runs on every single page.

Basically it checks to see if you are on the login page, if not, the script is ignored. If you are on the login page, it executes a controller->redirect() to the ldap_login page.

It relies on Event triggers (on_start specifically, if I remember correctly), which should be enabled by default if you are using the latest version of c5.
jolson replied on at Permalink Reply
This is actually not happening on my site. The ldap_login page is not rendering inline, the default login page is instead.

I added a redirect in custom login.php page to force ldap login for restricted pages - crude, temporary workaround.

Thanks in advance...

# concrete5 Version

# concrete5 Packages
Amiant CSS3 Menu (0.1), beigeGrid (1), Breadcrumbs (2.0), Clicky Web Analytics (1.2.0), Example FAQ (1.2.0), Force SSL (2.1), Iframe (1.0), LDAP Authentication (1.0), List files from set (1.0.2), Mobile Theme Switcher (1.1), PHP block by ND (1.0), Resposta Framework (1.1), Rigid Light - Theme (1.1.1), Who's Online (2.2).

# concrete5 Overrides
blocks/external_form, blocks/list_files_from_set, js/jquery.vticker.js, single_pages/login.php, themes/basicTheme, themes/beige1140

# Server Software
Apache/2.2.17 (Ubuntu)

# Server API

# PHP Version

# PHP Extensions
apache2handler, bcmath, bz2, calendar, Core, ctype, curl, date, dba, dom, ereg, exif, fileinfo, filter, ftp, gd, gettext, hash, iconv, json, ldap, libxml, mbstring, mcrypt, mhash, mssql, mysql, mysqli, openssl, pcre, PDO, pdo_dblib, pdo_mysql, Phar, posix, Reflection, session, shmop, SimpleXML, soap, sockets, SPL, standard, sysvmsg, sysvsem, sysvshm, tokenizer, wddx, xml, xmlreader, xmlwriter, zip, zlib.

# PHP Settings
max_execution_time - 120
log_errors_max_len - 1024
max_file_uploads - 20
max_input_nesting_level - 64
max_input_time - 60
memory_limit - 512M
post_max_size - 15M
safe_mode - Off
safe_mode_exec_dir - no value
safe_mode_gid - Off
safe_mode_include_dir - no value
sql.safe_mode - Off
upload_max_filesize - 15M
ldap.max_links - Unlimited
mssql.max_links - Unlimited
mssql.max_persistent - Unlimited
mssql.max_procs - Unlimited
mssql.textlimit - Server default
mysql.max_links - Unlimited
mysql.max_persistent - Unlimited
mysqli.max_links - Unlimited
mysqli.max_persistent - Unlimited
pcre.backtrack_limit - 100000
pcre.recursion_limit - 100000
session.cache_limiter - nocache
session.gc_maxlifetime - 7200
soap.wsdl_cache_limit - 5
safe_mode_allowed_env_vars - PHP_
safe_mode_protected_env_vars - LD_LIBRARY_PATH
ijessup replied on at Permalink Reply
It should not be rendered inline. When someone goes to the /login page, they should get redirected to /login_ldap instead.

This was one of the work-arounds needed since modifying the core code was not possible for this to be in a package and work with future versions of c5.

So you can follow the flow:
~/controller.php @line 42 (This runs on every single page load.)
~/models/login_redirect.php (Checks if we're on the /login page, redirects if so).
RoyS replied on at Permalink Reply
The issue with the LDAP filter not being saved only occurs when the Group Import Prefix is also blank. The issue is in controllers/dashboard/users/ldap.php. Line 36 should read:

if(!$prefix) $config->clear('LDAP_GROUP_IMPORT_PREFIX');
RoyS replied on at Permalink Reply
So, I've spent the last several days working on this add-on to try to make it work with my setup. The main differences are that I converted it to work with OpenLDAP instead of ActiveDirectory and that I added support for creating accounts in LDAP. I also tweaked some things to add an icon for the dashboard and to add a replacement for the register page. It's not what I would call perfect yet but it is doing what I need it to. If anyone needs to know the steps to get it working with an OpenLDAP schema or what changes were made I'm happy to oblige.
keithplummer replied on at Permalink Reply
Hi Roy,

I'd like to know what you did to get it to work with your OpenLDAP. That's the same setup that I have. I have it working with LDAP setup in the Dashboard, but when I try to log into the site I get an error saying invalid username or password. I know the information is correct because I use it on the config page in the Dashboard and it connects and authenticates.

When I log on using my concrete5 ID, I'm able to log in, but for some reason my LDAP users don't authenticate.

Any help would be greatly appreciated.


RoyS replied on at Permalink Reply
I did have a lot of trouble getting things set up just right. And, in fact, I rewrote some portions of the LDAP support so that I could create accounts from Concrete5. Here's what I ended up doing:

Default query



What may have tripped you up is that the Username isn't just the username. It sure tripped me up. In fact, I should have probably changed that title to something that indicated it was the DN for the user.
RoyS replied on at Permalink Reply
I should note that I may have changed some of the normal LDAP handling and I don't recall all the changes I made.
keithplummer replied on at Permalink Reply
Hi Roy,

Definitely the username got me tripped up, but it has me really tripped up now, because I don't understand why it works on the Dashboard configuration page, but the actual login page doesn't work. It appears to be using the same code, but for some reason the login page doesn't work, but the config page does. To make the Dasboard Config page work, I build the username in the code that gets passed to the LDAP server. I append the rest of the DN information to my username and that seems to work - for the Dashboard Config page, but not for the login page. It's driving me crazy.

Now I'm walking the code to figure out what is causing the Invalid Username or Passord because I can use the same username and password on the Config page and it works.

Thanks again.

RoyS replied on at Permalink Reply
The problem may be embedded into the LDAP handling. I may have re-written the user login portion to use the Open LDAP DN scheme. When I'm on my other computer tomorrow I can try pulling down the history of the file. You can always shoot me a private message and i can send you the code I use.
brownfieldc replied on at Permalink Reply
I have had this LDAP authentication working on two production workers. When I install it on my production server it looks alright (The warning doesn't show up, all I see is the : in red). But when I click to save my ldap settings it says page not found? Why would it do that especially since I have it all setup the same way as my test environment?
ijessup replied on at Permalink Reply
Not sure, I've never encountered this issue. Are you sure you have the php_ldap module installed and turned on?
brownfieldc replied on at Permalink Reply
Yea I have php-ldap. I get the no page found right after clicking save from putting in my ldap server and domain information, before I can put in a user name. It is just driving me batty since I have had this working on two other servers.
brownfieldc replied on at Permalink Reply
Just wanted to say I blew the server away and reinstalled and got it to work fine.... Must have farked something up in the original install.

I also wanted to point out that I can't add my groups in through the dashboard. I have to add them in manually through ldap_authenticator.php.
JedMeister replied on at Permalink Reply
Hi there. Firstly - newb alert!

I am running a Concrete5 website as a small non-profit intranet and ideally I'd like to use LDAP (Win 2k3 domain). I don't really have much knowledge of LDAP but I'm happy to read (and I'm pretty good with my googlefu!)

But... Perhaps I'm missing something completely... How do I configure this to find my Win 2k3 server? I'm assuming that I need to configure/define something somewhere for your addon to pick up? Would that be in the Concrete5 config/site.php file? Or do they go somewhere in your script? Or somewhere else?

After a fair bit of fiddling and reading and searching I've got nowhere. I don't expect you to give me all the answers and hold my hand, but just a little more initial config info would be awesome. I note that you said that I "need to use something like: CN=YourGroup,OU=Users,DC=YourDomain,DC=com" but where does that go? I think with just a little more info I will have a chance of getting this going... Even just an example and a location of where it has to go.

Thanks in anticipation. :)
ijessup replied on at Permalink Reply
Configuration page is located here: Dashboard -> Users and Groups -> LDAP
JedMeister replied on at Permalink Reply
Doh! Trust me to make it more complex than it needs to be! :)

Thanks so much!
hursey013 replied on at Permalink Reply
Just wanted to say thanks for posting this - I'm hoping to tie this is with an intranet project I'm working on. At this point all I have entered in is my LDAP Host Name/Address and Default Domain Name. Where should the credentials for "Poll Users Job Authentication" be coming from? I have limited experience with LDAP, so sorry if that's a dumb question. Right now, whatever I put in that box results in a blank white page - same goes for when I try to log in with any account other than the super user account through the LDAP login page.

Guess I'm just looking for a little bit more direction in terms of set up if possible for someone new to Active Directory/LDAP.

Thanks again for putting this together.
ijessup replied on at Permalink Reply
Go here: Dashboard -> Users and Groups -> LDAP
Fill in the "Poll Users Job Authentication" form.
Click "Save and Test". Make sure results are returned.

Go here: Dashboard -> System & Maintenance
Make sure the job "Poll LDAP Users" is enabled.
Click "Run Checked"
ijessup replied on at Permalink Reply
Quick note, polling users is only necessary if you need to preset advanced permissions for specific users. Otherwise, I would recommend setting permissions based on groups, and make sure that user is in the specific alias group in Active Directory.

A bug with the user polling job is that it sets the "admin" account to something random. So either make sure to change the "admin" account username to a specific AD account username, or you'll have to rehash a password for the admin account every time you run the poll users job.
samiam replied on at Permalink Reply
I am a humble newb and appreciate any feedback you are willing to share and thank you for posting this package.

I am having trouble when attempting to configure the basic authentication configuration settings. When I try to save our server and ldap domain information, I get a Page not found error. The URL that is displayed (sanitized):


I noticed earlier in the thread someone else had this problem, but you had not experienced the issue before. I'm hoping in the time since that post and the information in the URL may be of assistance.
ijessup replied on at Permalink Reply
It looks like the PHP tag <?= isn't getting interpreted. Make sure your server interprets PHP short hand.

If you can't figure out how to enable short tags, you can change the code.

<?= is equivalent to <?php print
samiam replied on at Permalink Reply
Thank you! My php config was set to allow interpretation of shortcut tags, but still failing to do so. I changed the code to the full listing and it is working now!
landollweb replied on at Permalink Reply
I ran into this, too. I ended up having to revise the code to use the full tags; setting short_open_tag to On did not fix it on this installation.

[Edit]: I'll have to take that back. Setting short_open_tag On did clear up the problem with un-parsed php in the url, but then another problem became apparent. (I'll make a separate post on it if there is nothing mentioned elsewhere in this discussion.)

I will also mention (forgive me if this has already come up) that when I was checking the recommendations for the use of short_open_tag with, I came across a few caveats about the fact that this configuration option may not be supported much longer. They didn't go so far as to say it was officially deprecated, but they are recommending that we adopt the practice of always using the full tags and keeping short_open_tag set Off, due to conflicts with other platforms such as xml.

But I will say I'm very happy to have found this - it will easily solve what I thought was going to be a big challenge. Thank you for letting us try it out while you're working on it. We will also be purchasing it once it hits the marketplace.
jolson replied on at Permalink Reply
Kudos and many thanks. This is working beautifully on my dev server. One quick question. I have been playing with site_theme_paths settings ($v->setThemeByPath('/ldap_login', "aisd");
) to skin the ldap_login page but can't seem to get it right. Any suggestions?
ijessup replied on at Permalink Reply
Where are you putting that code, and what have you defined $v as?
jolson replied on at Permalink Reply
It actually was working - sorry. BTW, will be delighted to purchase this package when it is ready (will need multiple licenses for our sites.)
landollweb replied on at Permalink Reply
I've made some progress with this, but there's still something I'm missing...

php_ldap installed and confirmed running - check

Package installed - check
- the LDAP Dashboard page is loading
- the Poll LDAP Users job is showing in the list of automated jobs (although I had to move poll_ldap_users.php from ../packages/ldap_auth/jobs to ../jobs before it would show up - not sure if this has anything to do with my problem or not.)

Using correct LDAP host name - think so but not 100% sure (it's the dns host name of our domain controller).

Using correct LDAP domain name - think so but not 100% sure (it's the domain name we all log into Active Directory under).

What's happening is, when I enter my AD user name and password on the LDAP Dashboard page and click Save, C5 says "Page Not Found".

If I try to run the Poll LDAP Users job from the automated jobs page, it just runs endlessly without really doing anything.

I'll keep digging into this and share what I find, but if anyone has any tips for troubleshooting this, I'd be grateful. Thanks!


[Update...] The Page Not Found thing was due to my having re-run my php install and forgotten to re-enable short tags support. This time, I just replaced all the short tags in ldap.php with the full <?php tags.

So now the poll job is running and now returning the following error message:
"No results returned. Check errors above.

Query: (&(objectCategory=person)(!(description=Built-in*))(!(name=*Mailbox*))(!(name=*Email*)))

Human: Only user accounts that don't have "Built-in" in thier description and don't have Mailbox or Email anywhere in their name."

[Update...] No results returned was caused by typo in the dc hostname. :-P It's now working. And by the way, in case anyone was wondering about whether it will run on 5.5, that's the version I'm running for this test.

Cheers, and thanks!
landollweb replied on at Permalink Reply
One minor issue I encountered is, C5's username restrictions can come into conflict with usernames obtained from LDAP.

For example, our active directory user names are created in the typical <first_name>.<last_name> format. C5 does not normally allow periods in usernames. So whenever you edit a user account whose name is formatted this way (such as when adding the user to a group), C5 squawks about an invalid username, even though you can log on with such a username and be able to function normally just about everywhere else.

I think this is a pretty easy thing to fix - if nobody else gets to a fix before I do, I'll post one when I can get to it.
madelyn replied on at Permalink Reply


Thanks :-)

madelyn replied on at Permalink Reply

How will change passwords from C5 with this plugin?

Madelyn :-)
haan replied on at Permalink Reply
Hi ijessup,

I've been a fan of this addon ever since you posted about it and I've been continuously checking on your progress. The last version is really nice!

There's just a slight detail that I can't seem to understand: The "Group Import Prefix" seems to act as some kind of "filter" and not setting a "Group Import Prefix" prevents Groups from being set at all.

In my Active Directories, my groups have all names like "sggTeacher", "sggStudent" and I'm comfortable with using those names as my concrete5 group names. However, if I don't set a prefix at all, the groups won't even be considered. This is due to line 109 in "ldap_authenticator.php" that only adds the group if a prefix has been set.

In my case, that means using "sgg" as a prefix and setting up group names "Teacher", "Student" ...

The question is ... why? What's your reasoning behind such an approach.

I would suggest that you modify your PHP code slightly so that, if someone specifies a prefix, it gets removed from the group names but in case someone doesn't set a prefix, that it just considers the group names as they are. The could would then become:

if($prefix) {
  if(!(strpos($group, $prefix) === false)) $groups[] = str_replace($prefix, '', $group);
} else {
  $groups[] = $group;

Another minor detail that you might want to look into when you've got the time: the login markup and CSS has changed in concrete 5.5 (I think) so the new "ldap_login" page is looking all strange. You might want to use the new HTML markup from the new login page.

Thanks for the awesome work,
jolson replied on at Permalink Reply 1 Attachment
I have run into an interesting issue and not been able to track down a resolution myself. If I apply force_ssl attribute to the ldap_login page in the sitemap, the page re-directs to (instead of and gives a page-not-found error.
jolson replied on at Permalink Reply
THe issue was with old version of force_ssl and C5v5.5x I updated force_ssl and all is well.
ckjs2015 replied on at Permalink Reply
Just a question - is the version up there with the Download link the latest version - or do i have to include all the changes suggested here by myself - how stable is this working already? Can there be said when this addon will be on the marketplace?
haan replied on at Permalink Reply
The Download link in the first post is the latest version and there hasn't been any further development from the original developer.

The problem is that concrete5 doesn't allow custom Login Controllers (without any hacks) that would allow to use ldap or other login methods. Any attempt to include another login method violates the marketplace rules and will definitely not make it in the marketplace at this time.

However, I have been able to successfully install, configure and run the aforementioned addon on my website. The addon in itself is stable but if you are not familiar with the concrete5 folder setup or not willing to dig into PHP code yourself, I wouldn't recommend installing it.
ijessup replied on at Permalink Reply
For those monitoring this thread, I've updated the package to work with version and below.
ntisteve replied on at Permalink Reply
Thanks for your excellent work on this concrete5 package. As posted elsewhere, as part of a client's evaluation of concrete5 for use as their intranet, they required that single signon (as opposed to single authentication) be available for any solution considered.

Although what I implemented for the proof-of-concept works fundamentally differently to your package, it was heavily inspired by your work.

The full details (and a copy of the code) is here:
ijessup replied on at Permalink Reply
Thank you for your contribution! At some point I may incorporate your SSO technique into the package. As time passes, it seems more and more people are interested in AD authentication with c5.

It may soon be time for a complete reworking to fit in with c5's third party authentication standards referenced in the roadmap.

Anyways, thank you again!
keithplummer replied on at Permalink Reply

I downloaded your attachment but I didn't find a readme file in the folder. Is there a set of instructions on how to implement the full ldap authentication? I have an ldap server available to use for credentials. I'm new to all of this so please be gentle.


ntisteve replied on at Permalink Reply
Hi Keith

If you're looking to implement LDAP authentication, download the file and unzip it to the packages folder of your concrete5 installation directory. Log into your concrete5 website as an admin and click the "Install" link which shows up when you hover on the "Dashboard" in the top right of your site. You should see "LDAP Authentication" listed there - simply install it.

If you're looking to implement Kerberos Single Sign-On using Active Directory, simply follow the readme.txt that is in the file on my other post.

Hope that helps :-)
keithplummer replied on at Permalink Reply

Keith asked me to reply to you from here. The install was easy just as you
explained it but the ldap setup is now where I'm stuck. I've filled out
the LDAP Host Name/Address, Default Domain Name, and the Default Base
Query and haven't had any success logging in to the ldap server. I'm
assuming the Username and password is the one for the ldap server? I think
where my issue lies is within the criteria filter and group import prefix.
Have you had anybody setup this up successfully with a mac ldap server and
if yes do you have any examples or information on how to set this part up.
I really appreciate all the assistance you have provided.

Thank you,

Alex Garcia

On 5/2/13 8:19 AM, "Keith Plummer" <> wrote:

>Seems to be pretty easy. Hopefully it really works this way.
>-----Original Message-----
>From: concrete5 Community []
>Sent: Wednesday, May 01, 2013 11:05 PM
>To: Keith Plummer
>Subject: Packaged LDAP Authentication [SOLVED] : Building with concrete5
ntisteve replied on at Permalink Reply
Hi Alex

I haven't had any experience with a mac LDAP server, although I doubt it would be all that different. A few things you could try:
- leave the criteria filter and group import prefix blank and test the connection (this will tell you if its this config that's the problem)
- check your LDAP server logs and make sure that your username/password is correct
- if all else fails, use the free LDAP Browser tool ( to verify your LDAP query

ijessup replied on at Permalink Reply
I just wanted to chime in and say "thank you" for providing support for my package.

You might want to consider writing an official "How To".

Anyways, +1 for community support. :)
keithplummer replied on at Permalink Reply
Hi Steve,

Thanks for the quick post. It's certaily appreciated.

It appears to be the config for some reason because I get invalid DN when I look in the LDAP logs. I've tried manipulating the various textboxes to see if I can get the correct configuration to the server, but I just can't seem to get there. Another intersting thing is when I leave the username field blank and click the save button, the username pops back into the field. Also, when I use the ldapsearch command on the server to test authentication/connection I have to use the -x for simple authentication. I didn't know if that would be helpful or not.

Is there a way I can show what's being posted to the server for authentication? I don't get much when I look at the logs. It just says invalid DN: admin@domain.lan. I know the configuration information that I'm trying to use works, because I use the same information on another server appliance.

Any help would be greatly appreciated.


sulate replied on at Permalink Reply
Just a long shot, but I think the LDAP "username" should also be in the "DN-format", for example: cn=Manager,dc=domain,dc=lan (or maybe something like: cn=admin@domain.lan,ou=People,o=MyHomeLdap)
keithplummer replied on at Permalink Reply
I've tried a couple of variations of what you suggested but still no luck. I was able to use this sequence in uid=user_name, cn=users, dc=domain,dc=lan on a web filters username field setting up ldap authentication and it worked but no luck here. Thanks for the help and any future help.

ijessup replied on at Permalink Reply
In the process of developing this package, I've noticed that each LDAP environment has it's own quirks.

Is it giving you a specific error message?

A lot of the connection variable are not exposed; and assumptions are made. Check out the ~/models/ldap_authenticator.php file - specifically the "query" function.

Also, check out [url][/url] for the documentation on how the ADODB connector works. (Search for LDAP on the page.)
keithplummer replied on at Permalink Reply
Thanks ijessup. This was a huge help. It definitely got me started in the right direction. One thing I'm curious about...with regards to the filter - does that return users or does it return groups that I belong too? What does the filter actually do for me? Am I trying to figure out if this user is an Admin user or a registered user? I'm not 100% sure. I'm sure I could figure it out, but it would take so much longer than just asking.

Thanks again for a great module. It sure makes things easier than forcing my clients to remember even more passwords.

RoyS replied on at Permalink Reply
Was just moving this to a new system and didn't remember to install the PHP LDAP module. The 'white screen of death' threw me off. So, I added the following to single_pages/dashboard/users/ldap.php right after the ccm-pane-body div (which might have been something I added)

if(!function_exists('ldap_connect')) {
                echo("<h2><span style='color: red;'>Warning! PHP LDAP module not installed!</span></h2>");

Hope that helps someone.
eljhonb replied on at Permalink Reply
Hi ijesup,
I have a question about your package.
I am trying it successfully but i notice that when you click logout you are calling index.php/login/logout instead of index.php/login_ldap/logout.
how can solve this? because I need to call logout function on login_ldap cause I have a custom logout.

thx in advance,
dbrost replied on at Permalink Reply
Hi All,

I am working on getting this set up and feel like I am missing something. Maybe it just can't be done.

If a user logs in what do I need to do to have that user auto join a user group.

Let me know if I am just missing something or this can't be done.

ijessup replied on at Permalink Reply
It's been a while since I've worked on this. If I remember correctly, there is an option to set a group prefix on your concrete5 site's LDAP settings page. So anyone in your AD that is in a group with that prefix will automatically be put into the concrete5 group without that prefix.

Prefix Setting: concrete5_
Group on AD: concrete5_Administrators
Group on you c5 site: Administrators

Does that make sense?
haan replied on at Permalink Reply
The relevant code for adding users to a group is located in "ldap_authenticator.php" in lines 104-121. However, as I already pointed out in a private message to the developer, the package requires you to specify a group prefix in order to even consider adding users to a group. This is because of line 111:

$prefix = Config::get('LDAP_GROUP_IMPORT_PREFIX');
// snip
if($prefix) if(!(strpos($group, $prefix) === false)) $groups[] = str_replace($prefix, '', $group);

Specifying a group prefix and naming the groups correctly should do the trick however.
jamfsupport replied on at Permalink Reply
Hi All,

I have been playing around with this add-on and it has worked for me so far. I love it.

Where we have it installed now we have been informed that in the future we may need to first authenticate with a service. Does anyone know of a way we would be able to add in the ability to do this?

Any suggestions would be helpful.

jolson replied on at Permalink Reply
Has anyone added using a bind account to this? Our AD access does not allow anonymous.
strawberry replied on at Permalink Reply
Hi, is ist possible to use this package with nested groups?
ijessup replied on at Permalink Reply
The package was set up to be as dead simple as possible. With that said, I haven't tried nested groups, nor did I design it with that in mind. It may not be hard to extend it to do what you're asking, but it's been a year and a half since I've touched it. So I can't say for sure.

As far as groups go, if I remember correctly, the only thing the package will do is put a c5 user into a c5 user group if the AD user is in an AD group with a given prefix to the same name as the c5 user group.

The main reason why I've kept this package in the forums and not put it in the marketplace is because it's never really a production ready package. It's more of a dev package that will hopefully get you running in the right direction.

It has worked well for the purposes that I used it for, but individual mileage will certainly vary. ;)
ntisteve replied on at Permalink Reply
+1 for this comment. We used ijessup's LDAP package as base from which we built a Kerberos/Active Directory based single signon solution for our corporate intranet. At the end of the day, we used very little of the package's code however without the ideas contained within it, it would have taken us much longer to develop.

We too looked at nested groups, however it hasn't become a big enough issue for us to spend the time developing this feature. Based upon the small amount of research we did do, I definitely believe it's possible to get it work.

Thanks again for your work on this ijessup BTW :-)

ijessup replied on at Permalink Reply
Just a heads up, authentication will change dramatically in concrete version 5.7. I'm expecting this package to be almost completely obsolete upon 5.7's release.

We are still a ways away from 5.7, but I would highly recommend looking into the authentication system changes now.
exchangecore replied on at Permalink Reply
For those of you not following the 5.7 project on github here's something that may interest you regarding ldap:

5.7's authentication has been made much more modular, so hopefully LDAP will be able to be integrated a lot easier now and probably will be able to make things pretty robust.
strawberry replied on at Permalink Reply
Thank you for publishing.

One thing I add for those who use it:

Domain Administrators are no longer treated in a special way. Instead you have to create a group "<your_prefix>_Administrators" and add the persons that shall be admins inside of it.


xlecm02 replied on at Permalink Reply 1 Attachment
Hi all,
I´m totally new in Linux so I´m sorry if I asked on some stupid questions.
I get as my school project to install concrete5 with LDAP.
I have installed concrete5 on our school debian server according instrucitons on this site
It works fine.
But I fail if I tried install LDAP. As I have read on this forum I downloaded and
Then I put on my var/www/concrete5 directory and run unzip command. When I look at dashboard --> install as admin I don´t see anything (as you can see in my attachment file)
at awaiting installation. So what I did wrong? I will be very grateful for any solution to my problem.
Mnkras replied on at Permalink Reply
In the /packages directory.
xlecm02 replied on at Permalink Reply
Thank you very much for your advice, now I finally see it
theneptune replied on at Permalink Reply
Its Really appreciate. Thanks.
vikramal1993 replied on at Permalink Reply
I am not able to install the package in concrete5 V8.2.1. I downloaded both zip files and replaced the ldap_authenticator.php file in helpers directory. Any suggestion how to install it.