Name |
Crowd as an LDAP Server |
---|---|
Version |
1.0 |
Product Versions |
Crowd v1.0.6 |
Author(s) |
Robert Castaneda [CODEGEIST:CustomWare] , Daren Klamer [CODEGEIST:CustomWare] |
Homepage |
|
Price |
FREE! Priceless! |
License |
N/A |
JavaDocs |
|
IssueTracking |
|
Download JAR |
|
Download Source |
Code, what code? This one is about re-use! |
Description/Features
A layer to turn Crowd into an LDAP server
Motivation - a non-Atlassian product to integrate into our environment. The product supports LDAP authentication, we want to use our Crowd deployment as the central repository of users, rather than setting up an LDAP repository just for this application.
A picture is a thousand words - here is the end result in JXplorer of users listed from Crowd via LDAP:
The requirement is to have no Java/J2EE/Atlassian based products use crowd as the central authentication mechanism via LDAP. To achieve this, we have used Penrose - http://penrose.safehaus.org/ and have configured it to read user/password information from the Crowd database as well as implement a password decrypt/decode function in Penrose so that it can authenticate using the same passwords that are stored in Crowd without duplicating user information. A user in Crowd, is a user in LDAP. The diagram shows the setup below:
Whilst not a plugin that runs within an Atlassian product, it's another solution that can bring outside technologies into the Atlassian world.
How an external application authenticates over LDAP can be different from one application to another. This example has been tested using Crowd itself, that is , using the Penrose LDAP server as a Crowd Directory service and a Crowd external Application setup to test against this directory.
At any time, Crowd can update their algorithm for storing passwords. The mechanism described here makes us of the fact that having access to the right data, a password can be reverse engineered/constructed from the Crowd database. If this ability changes in future, then this will need to be updated, probably to use the
<pwd> type syntax.
As always, an application/infrastructure such as Crowd is only as secure as the infrastructure -database/os - that it runs on.
Steps to setup
- Download and install Penrose Server and Studio from http://penrose.safehaus.org/. This example was created and tested with version 1.1.2
- Setup and connect Penrose Studio as default - you will also be required to setup a jdbc driver to your database - the instructions at http://docs.safehaus.org/display/PENROSE/Installing+JDBC+Driver will be invaluable for this!
- Once inside Penrose Studio, you need to Create a Connection. Here are our settings - they are for EnterpriseDB.
- We then create a Source. In Crowd, we created a View rather than accessing the tables directly. The main table that you need access to is REMOTEPRINCIPALCREDENTIALS
- We then and add a New Dynamic Entry, not a "Dynamic Entry from Source". Within that entry definition, we define the source within the dynamic entry.
- You can then test with an LDAP browser, such as a Crowd Principal search or JXplorer - http://www.jxplorer.org/
Code
The following code decrypts passwords stored in Crowd, note that you need to retrieve the RETRIEVE_ME_FROM_YOUR_CROWD_DATABASE parameter from your DB. To retrieve this parameter, execute the following SQL from the Crowd database:
select * from "SERVERPROPERTY" where "NAME" = 16
The code is below.
import sun.misc.BASE64Decoder; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.SecretKey; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; // Buffer used to transport the bytes from one stream to another byte[] buf = new byte[CODEGEIST:1024]; try { byte[] hash = new BASE64Decoder().decodeBuffer( RETRIEVE_ME_FROM_YOUR_CROWD_DATABASE ); SecretKey key = new SecretKeySpec( hash, "DES" ); DESKeySpec paramSpec = new DESKeySpec( hash ); Cipher dcipher = Cipher.getInstance( "DES" ); dcipher.init( Cipher.DECRYPT_MODE, key ); ByteArrayInputStream bis = new ByteArrayInputStream( new BASE64Decoder().decodeBuffer( thepwd ) ); InputStream in = new CipherInputStream( bis, dcipher ); // Read in the decrypted bytes and write the cleartext to out int numRead = 0; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while( ( numRead = in.read( buf ) ) >= 0 ) { bos.write( buf, 0, numRead ); } return new String( bos.toByteArray() ) ; } catch( Exception e ) { e.printStackTrace(); }
Screenshots
Screenshots |
||
---|---|---|
6 Comments
Collin Summers
What timing... I was just getting ready to use Penrose for an app that does not have a crowd adapter...
Now I can use Crowd which will make my life much easier...
I have followed the directions ... as minimal as they are ... And I can not get any users to return I get "Search "cn=users,ou=Users,dc=example,dc=com" with scope base and filter "(objectClass=*)
[05/14/2007 14:43:23] Search operation succeded.
[05/14/2007 14:43:23] Search operation returned 0 entries.
" every time I try to look at the users via JXplorer...
Should the userPassword code be entered as text or as an expression? Any suggestions for further debugging?
Thanks,
Collin
Robert Castaneda[ServiceRocket]
Hi Colin,
Thanks for trying this out. The password piece is only required if you want to authenticate against LDAP, not browse it. When you craete your source in Penrose Studio, are you able to see the list of results within Penrose Studio itself? this is the first step that needs to be verified before trying to access it externally.
Robert Castaneda[ServiceRocket]
The SQL for the view is...
Devon Hillard
Is there any way to get crowd groups linked to the users exposed through ldap? We want to tie into LDAP and auth based on what group a user is in. Etc...
I'm sure it's possible, but the penrose docs are pretty lacking imho.
Thanks for any help!
Andreas Ebbert-Karroum
Hi,
thanks for the nice extension Before trying it out thought, I would like to understand if only users configured internally in Crowd are exposed (which I assume, since it's reading the user information from the Crowd database), or if also directories, that are connected to Crowd are then immediatly accessible?
I assume that other directories, that are connected to crowd, should be connected to penrose as well, so that you have all users merged in one LDAP.
Andreas
Lee D
Is there any way to get this to work with crowd 2, it looks like the schema has changed?
Cheers
Lee