Lightweight Directory Access Protocol (LDAP) is a standard way many organizations maintain user credentials and group memberships. Spinnaker uses the standard “bind” approach for user authentication. This is a fancy way of saying that Gate uses your username and password to login to the LDAP server, and if the connection is successful, you’re considered authenticated. Note that there is a fair bit of crossover between the authorization and authentication settings.
Make sure you’re using Halyard 1.20 or later as that adds the ability to set the manager user/password settings.
You can use a prior version, but you will need to use a gate-local.yml
to define the manager properties instead of being able
to use Halyard.
If the manager Domain Name (DN) is NOT set, all searches attempt to use the user currently logging in. You’ll often see errors in the log files tied to “bind failures” and LDAP error codes.
Escaping things like spaces is handled by the library. You do NOT need to use LDAP escape codes to handle spaces.
We highly suggest the use of SSL for the LDAP connection (ldaps://...
). Otherwise, user passwords are passed in
clear text over the wire.
Ports commonly used or referenced:
ldaps
)When a port is not specified, ldap://host/whatever
implies port 389 by default. ldaps://host/whatever
uses port 636 by
default.
url
(ldaps://my.server/a/b/c
→ a/b/c
)com.netflix.spinnaker.fiat.roles.ldap.LdapUserRolesProvider
log level is at debug, you should
see Root DN: <the actual root DN extracted>
--user-search-filter
is provided:--user-search-base
OR the root (would be a/b/c
in this example) if user-search-base is not set.--user-search-filter="(d={0})"
where uid=<the username as typed in>
, such as jdoe
.user-search-filter
is not provided:user-dn-pattern
. In the case below, the user jdoe
would have a full DN of
uid=jdoe,ou=users,dc=mydomain,dc=net
.For example, given the following parameters:
dc=my-organization,dc=com
user-dn-pattern
is uid={0},ou=users
jdoe
The full, unique DN would be uid=jdoe,ou=users,dc=my-organization,dc=com
.
When jdoe
is trying to log in, this full user DN is constructed and passed to the LDAP server with
their password. The server hashes the password and compares it to its own hashed version. If
successful, the bind (aka connection) is successful and Gate creates a session.
In the above example, you could test with:
//Search using manager DN, manager password on url with base of "X"
# When: --user-search-filter=(uid={0}) --user-search-base=DC=USERS,OU=Y,O=io
ldapsearch -D "MANAGER_DN" -w 'MANAGER_PASSWORD' -H ldaps://1.2.3.4 -x -b "DC=USERS,OU=Y,O=io" "(UID=USERNAME)"
Without a user-search-base
//Search using manager DN, manager password on url with base of "X"
# When: --user-search-filter=(uid={0})
ldapsearch -D "MANAGER_DN" -w 'MANAGER_PASSWORD' -H ldaps://1.2.3.4 -x "(UID=USERNAME})"
Without a user-search-filter
//Search using manager DN, manager password on url with base of "X"
# When: --user-dn-pattern=(uid={0},ou=users)
ldapsearch -D "MANAGER_DN" -w 'MANAGER_PASSWORD' -H ldaps://1.2.3.4/OU=Y,O=io -x "(CN=USERNAME,OU=users,OU=Y,O=IO))"
You can use hal config
to enable and configure LDAP. Here’s an example:
hal config security authn ldap edit --user-dn-pattern="uid={0},ou=users" \
--url=ldaps://ldap.my-organization.com:636/dc=my-organization,dc=com
hal config security authn ldap enable
You can also use --user-search-base
(optional) and --user-search-filter
if the simpler
--user-dn-pattern
does not match what your organization uses for userDn
. We don’t explore this
use case here, but you can read up more on LDAP search filters
here
.
We recommend NOT using the --user-dn-pattern
argument for AD. The following issue has been reported in an issue ticket:
“userDnPattern should remain unset - AD groups store user DNs in the memberOf attribute; finding DNs from sAMAccountNames is easily doable but not with a simple, single-level pattern. The DN contains the the CN, and that can’t really be constructed without sub searches. userSearchFilter takes precedence if there’s no user-dn-pattern set.”
Here’s the raw settings that will eventually be there in Gate as an example.
ldap:
enabled: true
url: ldaps://somethingsomething:686/ou=users,ou=company,o=com
userSearchFilter: (&(objectClass=user)(sAMAccountName={0}))
managerDn: CN=SVC_LDAP_USER_RO,OU=service-users,OU=company,O=com
managerPassword: super-secret-password
The managerUser will then find a user in your ou=users,ou=company,o=com directory via a subtree search. You should be able to set the user-search-base parameter vs. including it on the URL to have it specified separately.
Last, here are the Halyard commands to configure these:
hal config security authn ldap enable
hal config security authn ldap edit \
--manager-dn 'CN=blah,OU=blah,OU=blah,O=blah' \
--user-search-filter '(&(objectClass=user)(sAMAccountName={0}))' \
--url ldaps://blah:686/searchbase
## This one will prompt you for the password don't set it on the command
hal config security authn ldap edit --manager-password
Now that you’ve authenticated the user, proceed to setting up their authorization .
Review the general authentication workflow .
Use an Incognito window . Close all Incognito windows between attempts.
I’m getting the “Bad Credentials” exception mentioned above, but my username and password is correct!
Ensure that the fully qualified user DN is correct. Confirm with your LDAP administrator how your organization’s LDAP directory is structured.