NUcore uses Devise for authentication,
and the ldap_authenticatable
Devise module for LDAP authentication.
When LDAP is enabled on NUcore Devise will try to authenticate users against both the LDAP server and the local users table. Whichever works first wins. If neither works login is denied.
Start by making sure the gem "ldap_authentication", path: "vendor/engines/ldap_authentication"
line is present in your Gemfile. Then set uses_ldap_authentication: true
in config/settings.yml
.
NUcore will activate LDAP authentication if a configuration file exists. The example config file provided with NUcore is enough to get started:
cp config/ldap.yml.template config/ldap.yml
The default settings are for an LDAP server running on localhost
port 636,
which should work for the test LDAP server described below.
Change the host:
value if you are using an external LDAP server.
LDAP authenticates users with a distinguished name (dn
), which is typically
composed of multiple LDIF attributes. One of the attributes of the dn
will
specify the user's login. The additional attributes, for NUcore, are expected
to be consistent across all users.
LDAP users allowed to access NUcore must have a password-less record in
NUcore's users table. The record's username attribute must correspond to the
login part of the user's LDAP dn
. The LDIF attribute identifying the login
must be the value of ldap.yml
's attribute:
key.
The additional LDIF attributes that make up the remainder of the LDAP dn
must
be the value of the base:
key.
The easiest thing to do is add an LDAP server in docker-compose
.
- Set the
LDAP_HOST
environment variable. If you're running the main app outside docker, you can runecho LDAP_HOST=localhost
or just leaveLDAP_HOST
unset (localhost
is set as the default value inldap.yml
). If you're running the main app in docker, addLDAP_HOST=ldap
to the main app'senvironment
indocker-compose.yml
:
app:
environment:
- LDAP_HOST=ldap
- Add the
ldap
andldap-admin
services todocker-compose.yml
. Theldap-admin
service is optional:
ldap:
image: osixia/openldap
command: "--copy-service"
ports:
- "636:636"
volumes:
- "ldap-data:/var/lib/ldap"
- "slapd-config:/etc/ldap/slapd.d"
# Loads some default users into the database
- "./vendor/engines/ldap_authentication/spec/fixtures:/container/service/slapd/assets/config/bootstrap/ldif/custom"
# Optional administrative website
ldap-admin:
image: osixia/phpldapadmin
ports:
- "8081:80"
depends_on:
- ldap
environment:
- PHPLDAPADMIN_LDAP_HOSTS=ldap
- PHPLDAPADMIN_HTTPS=false
- The directories
/var/lib/ldap
(LDAP database files) and/etc/ldap/slapd.d
(LDAP config files) are used to persist the schema and data information, and should be mapped as volumes so the files are saved outside the container. More info on this at https://github.com/osixia/docker-openldap#data-persistence. Addldap-data
andslapd-config
to your volumes list indocker-compose.yml
:
volumes:
slapd-config:
driver: local
ldap-data:
driver: local
- Bring up the services:
docker-compose up ldap
docker-compose up ldap-admin
- Confirm the
ldap-admin
service is up and running:
- Go to: http://localhost:8081
- Login DN: cn=admin,dc=example,dc=org
- Password: admin
For testing you'll need at least one organization in the LDAP directory. If you are using
the ldap-admin
service, the organization should already exist for you.
To create an organization:
Create a org.ldif
file in LDAP data interchange format. Here's an example:
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
dc: example
o: Table XI
ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin -f org.ldif
You will also need at least one user in the LDAP directory. To create a user:
Create a usr.ldif
is a file in LDAP data interchange format. Here's an example:
# see vendor/engines/ldap_authentication/spec/fixtures/chico.user.ldif
dn: uid=cgreen,dc=example,dc=org
uid: cgreen
cn: Chico Green
gn: Chico
sn: Green
mail: [email protected]
userPassword: secret
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
If you are using the ldap-admin
service, you can copy and paste an ldif
configuration
using the "Import" feature.
ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin -f usr.ldif
ldapsearch -x -D "cn=admin,dc=example,dc=org" -w admin -b "dc=example,dc=org" "uid=*"
You should see output similar to this:
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=org> with scope subtree
# filter: uid=*
# requesting: ALL
#
# cgreen, example.org
dn: cn=cgreen,dc=example,dc=org
uid: cgreen
cn: Chico Green
givenName: Chico
sn: Green
mail: [email protected]
userPassword:: bm90Z3VtcA==
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Create a password-less User
:
bundle exec rails console
[1] pry(main)> User.create!(username: "cgreen", first_name: "Chico", last_name: "Green", email: "[email protected]")
Try logging in to NUcore with username cgreen
and password secret
.
You should login successfully, and you should see activity in the LDAP server's
standard output.