Redo LDAP config in the main configuration and add role mappings

This commit is contained in:
Janne Heß 2022-01-21 21:20:02 +01:00 committed by Graham Christensen
parent 76b4b43ac5
commit 61d74a7194
4 changed files with 71 additions and 47 deletions

View file

@ -108,47 +108,70 @@ Using LDAP as authentication backend (optional)
Instead of using Hydra\'s built-in user management you can optionally
use LDAP to manage roles and users.
The `hydra-server` accepts the environment variable
*HYDRA\_LDAP\_CONFIG*. The value of the variable should point to a valid
YAML file containing the Catalyst LDAP configuration. The format of the
configuration file is describe in the
[*Catalyst::Authentication::Store::LDAP*
documentation](https://metacpan.org/pod/Catalyst::Authentication::Store::LDAP#CONFIGURATION-OPTIONS).
An example is given below.
This is configured by defining the `<ldap>` block in the configuration file.
In this block it\'s possible to configure the authentication plugin in the
`<config>` block, all options are directly passed to `Catalyst::Authentication
::Store::LDAP`. The documentation for the available settings can be found [here]
(https://metacpan.org/pod/Catalyst::Authentication::Store::LDAP#CONFIGURATION-OPTIONS).
Roles can be assigned to users based on their LDAP group membership
(*use\_roles: 1* in the below example). For a user to have the role
*admin* assigned to them they should be in the group *hydra\_admin*. In
general any LDAP group of the form *hydra\_some\_role* (notice the
*hydra\_* prefix) will work.
Note that the bind password (if needed) should be supplied as an included file to
prevent it from leaking to the Nix store.
credential:
class: Password
password_field: password
password_type: self_check
store:
class: LDAP
ldap_server: localhost
ldap_server_options.timeout: 30
binddn: "cn=root,dc=example"
bindpw: notapassword
start_tls: 0
start_tls_options:
verify: none
user_basedn: "ou=users,dc=example"
user_filter: "(&(objectClass=inetOrgPerson)(cn=%s))"
user_scope: one
user_field: cn
user_search_options:
deref: always
use_roles: 1
role_basedn: "ou=groups,dc=example"
role_filter: "(&(objectClass=groupOfNames)(member=%s))"
role_scope: one
role_field: cn
role_value: dn
role_search_options:
deref: always
Roles can be assigned to users based on their LDAP group membership. For this
to work *use\_roles = 1* needs to be defined for the authentication plugin.
LDAP groups can then be mapped to Hydra roles using the `<role_mapping>` block.
Example configuration:
```
<ldap>
<config>
<credential>
class = Password
password_field = password
password_type= self_check
</credential>
<store>
class = LDAP
ldap_server = localhost
<ldap_server_options>
timeout = 30
debug = 2
</ldap_server_options>
binddn = "cn=root,dc=example"
bindpw = notapassword
start_tls = 0
<start_tls_options>
verify = none
</start_tls_options>
user_basedn = "ou=users,dc=example"
user_filter = "(&(objectClass=inetOrgPerson)(cn=%s))"
user_scope = one
user_field = cn
<user_search_options>
deref = always
</user_search_options>
# Important for role mappings to work:
use_roles = 1
role_basedn = "ou=groups,dc=example"
role_filter = "(&(objectClass=groupOfNames)(member=%s))"
role_scope = one
role_field = cn
role_value = dn
<role_search_options>
deref = always
</role_search_options>
</config>
<role_mapping>
# Make all users in the hydra_admin group Hydra admins
hydra_admin = admin
# Allow all users in the dev group to restart jobs
dev = restart-jobs
</role_mapping>
</ldap>
```
This example configuration also enables the (very verbose) LDAP debug logging
by setting `config.ldap_server_options.debug`.
Embedding Extra HTML
--------------------

View file

@ -522,7 +522,6 @@
TextTable
UUID4Tiny
XMLSimple
YAML
];
};

View file

@ -6,6 +6,7 @@ use parent 'Catalyst';
use Moose;
use Hydra::Plugin;
use Hydra::Model::DB;
use Hydra::Helper::Nix qw(getHydraConfig);
use Catalyst::Runtime '5.70';
use Catalyst qw/ConfigLoader
Static::Simple
@ -19,7 +20,6 @@ use Catalyst qw/ConfigLoader
PrometheusTiny/,
'-Log=warn,fatal,error';
use CatalystX::RoleApplicator;
use YAML qw(LoadFile);
use Path::Class 'file';
our $VERSION = '0.01';
@ -43,9 +43,7 @@ __PACKAGE__->config(
role_field => "role",
},
},
ldap => $ENV{'HYDRA_LDAP_CONFIG'} ? LoadFile(
file($ENV{'HYDRA_LDAP_CONFIG'})
) : undef
ldap => Hydra::Helper::Nix::getHydraConfig->{'ldap'}->{'config'}
},
'Plugin::ConfigLoader' => {
driver => {

View file

@ -59,7 +59,9 @@ sub doLDAPLogin {
my $user = $c->find_user({ username => $username });
my $LDAPUser = $c->find_user({ username => $username }, 'ldap');
my @LDAPRoles = grep { (substr $_, 0, 6) eq "hydra_" } $LDAPUser->roles;
my @LDAPRoles = $LDAPUser->roles;
my %ldap_config = %{Hydra::Helper::Nix::getHydraConfig->{'ldap'}};
my %role_mapping = $ldap_config{'role_mapping'} ? %{$ldap_config{'role_mapping'}} : ();
if (!$user) {
$c->model('DB::Users')->create(
@ -79,8 +81,10 @@ sub doLDAPLogin {
});
}
$user->userroles->delete;
if (@LDAPRoles) {
$user->userroles->create({ role => (substr $_, 6) }) for @LDAPRoles;
foreach my $ldap_role (@LDAPRoles) {
if (%role_mapping{$ldap_role}) {
$user->userroles->create({ role => $role_mapping{$ldap_role} });
}
}
$c->set_authenticated($user);
}