Introduction
The Shiny Server Admin Guide provides detailed information about all configuration directives that could be used to configure your Shiny Server Pro for LDAP and/or Active Directory authentication.
In this document we provide some examples that could be used as a starting point. Additional examples can be found in the LDAP example article.
We strongly recommend that before you start configuring for LDAP/AD, first enable TRACE logging on the server. For instructions on how to modify logging level refer to this section of the Admin Guide.
Basic LDAP Configuration
For some LDAP structures a very simple configuration listed below will work:
auth_ldap ldap://localhost/dc=company,dc=com {
}
This configuration uses the default bind template of: uid={username},ou=People,{root}
to bind the user. With this configuration, a user logging in as "myname" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'uid=myname,ou=People,dc=company,dc=com
And this works as long as user's DN in the LDAP matches that string.
But in most cases the format of the user's DN is different than the default, and you would need to define that as in the following example where users belong to ou=Corporate
:
auth_ldap ldap://localhost/dc=company,dc=com {
user_bind_template "cn={username},ou=Corporate,{root}";
}
With this configuration, user logging in as "myname" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'cn=myname,ou=Corporate,dc=company,dc=com'
LDAP and Groups:
Shiny Server Pro provides the option to authorize access to the Admin console and/or your Shiny applications based on group membership. Here is an example that uses group_filter
directive to find groups based on user's DN and group member
attribute:
auth_ldap ldap://localhost/dc=company,dc=com {
group_filter "member={userDN}";
user_bind_template "cn={username},ou=People,{root}";
}
User logging in as "myname" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'cn=myname,ou=People,dc=company,dc=com
...
[TRACE] shiny-server - Retrieving groups for user 'cn=username,ou=People,dc=company,dc=com' using filter: '(member=cn=username,ou=People,dc=company,dc=com)' in 'ou=Groups,dc=company,dc=com'
[TRACE] shiny-server - Discovered groups: Administrators
As you can see in the last line, one or more groups were found for this user, and therefore group-based authorization would work for this user.
If you do not define group_filter
, Shiny Server by default uses uniqueMember={username}
as the filter, and searches in ou=Groups
, as the following log message shows:
[TRACE] shiny-server - Retrieving groups for user 'cn=myname,ou=People,dc=company,dc=com' using filter: '(uniqueMember=myname)' in 'ou=Groups,dc=company,dc=com
Most likely your LDAP structure has a different groups root than ou=Groups
. You can configure that using group_search_base
directive as in the following example:
auth_ldap ldap://localhost/dc=company,dc=com {
group_filter "member={userDN}";
group_search_base ou=AdminGroups;
user_bind_template "cn={username},ou=People,{root}";
}
Groups in different subtrees:
For cases that users from a variety of groups will be logging in, and groups could belong to different LDAP subtrees, a configuration like the following might be needed:
auth_ldap ldap://localhost/dc=company,dc=com {
group_search_base "";
group_filter "member={username}";
user_bind_template "{username}@company.com";
user_filter "userPrincipalName={userBind}";
}
Secure LDAP:
If you're using secure LDAP, you can replace ldap
protocol with ldaps
protocol in all of the above examples. For example:
auth_ldap ldaps://localhost/dc=company,dc=com {
group_filter "member={userDN}";
user_bind_template "cn={username},ou=People,{root}";
}
Basic Active Directory Configuration:
For some Active Directory structures a very simple configuration listed below will work:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
}
This configuration uses the default values provided for user_bind_template
and user_filter
to bind the user. And it behaves the same as the following configuration:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_bind_template "{username}@company.com";
user_filter "userPrincipalName={userBind}";
}
With this configuration, a user logging in as "kim" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'kim@company.com'
..
[TRACE] shiny-server - Using user DN: CN=Kim Smith,CN=Users,DC=company,DC=com
If the configuration has an incorrect filter pattern, as in the following example:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_bind_template "{username}@company.com";
user_filter "userPrincipalName={username}";
}
authentication will fail. A user logging in as "kim" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'kim@company.com'
..
[WARN] shiny-server - Unable to find any user using the LDAP query '(userPrincipalName=kim)' with base 'cn=Users,DC=company,dc=com'
INFO] shiny-server - Failed login attempt for user: 'kim'
You can further define user_search_base
directive to specify the subtree in which users are stored. The default value for this is cn=Users
. Not defining user_search_base
is similar to defining it as follows:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_filter "userPrincipalName={userBind}";
user_search_base "CN=Users";
}
With this configuration, a user logging in as "kim" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'kim@company.com'
..
[TRACE] shiny-server - Using user DN: CN=Kim Smith,CN=Users,DC=company,DC=com
Notice the pattern for the DN in the last line which uses CN=Users
. Change the user_search_base
based on the structure of your Active Directory and how/where the users are stored. For example if users are in Corporate
subtree, use the following:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_filter "userPrincipalName={userBind}";
user_search_base "CN=Corporate";
}
If you notice error messages like the following in the shiny-server.log file:
[ERROR] shiny-server - Error with LDAP query: 0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of:
'DC=company,DC=com'
this could indicate that the pattern defined in user_search_base
is incorrect.
Active Directory and groups
As mentioned earlier, Shiny Server Pro provides the option to authorize access to Admin and/or applications based on group membership.
The default value of group_filter
for auth_active_dir
is: member:1.2.840.113556.1.4.1941:={userDN}
Not defining group_filter
is similar to using the following configuration:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_filter "userPrincipalName={userBind}";
group_filter "member:1.2.840.113556.1.4.1941:={userDN}";
}
With this configuration, a user logging in as "kim" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'kim@company.com'
..
[TRACE] shiny-server - Using user DN: CN=Kim Smith,CN=Users,DC=company,DC=com
..
[TRACE] shiny-server - Retrieving groups for user 'CN=Kim Smith,CN=Users,DC=company,DC=com' using filter: '(member:1.2.840.113556.1.4.1941:=CN=Kim Smith,CN=Users,DC=company,DC=com)' in 'cn=Users,DC=company,dc=com'
[TRACE] shiny-server - Discovered groups: kim-grp,managers-grp
Define the correct group_filter
pattern based on the structure of your Active Directory and the group/user attributes. For example if you have an attribute called memberID
instead of member
, use the following configuration:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_filter "userPrincipalName={userBind}";
group_filter "memberID={userDN}";
}
Note that if you do not use the correct attribute, you will not see any errors in the shiny-server.log file, but there won't be any groups returned by the query, and therefore group-based authorization would fail. What you see in the shiny-server.log file is as follows:
[TRACE] shiny-server - Retrieving groups for user 'CN=Kim Smith,CN=Users,DC=company,DC=com' using filter: '(memberID:=CN=Kim Smith,CN=Users,DC=company,DC=com)' in 'cn=Users,DC=company,dc=com'
[TRACE] shiny-server - Discovered groups:
Notice the empty list of "discovered groups".
Groups in different Active Directory subtrees:
For cases that users from a variety of groups will be logging in, and groups could belong to different Active Directory subtrees, a configuration like the following might be needed:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_filter "userPrincipalName={userBind}";
group_filter "member={userDN}";
group_search_base "";
}
Too many groups:
There could be cases where a user belongs to too many groups. This could cause problems if the returned list of groups is a string of more than (roughly) 3K characters. For such cases we recommend that you filter the groups further by defining a pattern match as in the following example:
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
user_filter "userPrincipalName={userBind}";
group_filter "&(cn=*Shiny*)(member={userDN})";
group_search_base "";
}
For details on how to define query patterns refer to the following LDAP documentation:
https://technet.microsoft.com/en-us/library/aa996205%28v=exchg.65%29.aspx
Double Bind:
Shiny Server Pro supports double-bind to LDAP/AD. This is done by defining base_bind
directive which specifies a user DN and password for the initial LDAP bind operation. The authenticated connection allows Shiny Server Pro to search for a user's DN. The discovered DN is subsequently provided to a second bind operation.
auth_active_dir ldaps://localhost/dc=company,dc=com company.com{
base_bind "CN=Jim Jones,CN=Users,{root}" "<path_to_password_file>";
user_filter "userPrincipalName={userBind}";
group_filter "member={userDN}";
group_search_base cn=Users;
}
With this configuration, a user logging in as "kim" will see the following in the shiny-server.log:
[TRACE] shiny-server - Attempting to bind LDAP user 'CN=Jim Jones,CN=Users,DC=company,dc=com'
...
[TRACE] shiny-server - Attempting to bind LDAP user 'CN=Kim Smith,CN=Users,DC=company,DC=com'
...
[TRACE] shiny-server - Retrieving groups for user 'CN=Kim Smith,CN=Users,DC=company,DC=com' using filter: '(member=CN=Kim Smith,CN=Users,DC=company,DC=com)' in 'cn=Users,DC=company,dc=com'
[TRACE] shiny-server - Discovered groups: kim-grp, managers
Note that user_filter
directive must be defined whenever using base_bind
with auth_ldap
.
Comments