Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 48c71a4b

Von Moritz Bunkus vor mehr als 5 Jahren hinzugefügt

  • ID 48c71a4b51f5359a7ab7e9bc51280baf9bc9b9b2
  • Vorgänger 4d015385
  • Nachfolger e6795d92

Auth: Unterstützung für multiple Authentifizierungsbackends

Über den Parameter "module" kann man nun multiple Backends angeben,
die nacheinander versucht werden, bis ein Erfolg gemeldet wird oder
die Liste durchlaufen wurde.

Zusätzlich kann man LDAP-Module mehrfach angeben. Damit
unterschiedliche Konfigurationen für jede Modulinstanz benutzt werden
können, wurde die Syntax erweitert: für "LDAP:Config-Abschnitts-Name"
wird "[authentication/Config-Abschnitts-Name]" benutzt. Zwecks
Rückwärtskompatibilität sucht "LDAP" ohne Angabe eines Namens nach dem
bisher auch verwendeten Abschnitt "[authentication/ldap]".

Nützlich ist das Ganze z.B., um einen LDAP-Fallback-Server angeben zu
können, der benutzt wird, wenn der Hauptserver nicht erreichbar sein
sollte.

Unterschiede anzeigen:

SL/Auth.pm
5 5
use Digest::MD5 qw(md5_hex);
6 6
use IO::File;
7 7
use Time::HiRes qw(gettimeofday);
8
use List::MoreUtils qw(uniq);
8
use List::MoreUtils qw(any uniq);
9 9
use YAML;
10 10
use Regexp::IPv6 qw($IPv6_re);
11 11

  
......
72 72
    delete $self->{column_information};
73 73
  }
74 74

  
75
  $self->{authenticator}->reset;
75
  $_->reset for @{ $self->{authenticators} };
76 76

  
77 77
  $self->client(undef);
78 78
}
......
145 145
    $self->{DB_config}   = $::lx_office_conf{'authentication/database'};
146 146
  }
147 147

  
148
  if ($self->{module} eq 'DB') {
149
    $self->{authenticator} = SL::Auth::DB->new($self);
148
  $self->{authenticators} =  [];
149
  $self->{module}       ||=  'DB';
150
  $self->{module}         =~ s{^ +| +$}{}g;
150 151

  
151
  } elsif ($self->{module} eq 'LDAP') {
152
    $self->{authenticator} = SL::Auth::LDAP->new($::lx_office_conf{'authentication/ldap'});
153
  }
152
  foreach my $module (split m{ +}, $self->{module}) {
153
    my $config_name;
154
    ($module, $config_name) = split m{:}, $module, 2;
155
    $config_name          ||= $module eq 'DB' ? 'database' : lc($module);
156
    my $config              = $::lx_office_conf{'authentication/' . $config_name};
154 157

  
155
  if (!$self->{authenticator}) {
156
    my $locale = Locale->new('en');
157
    $self->mini_error($locale->text('No or an unknown authenticantion module specified in "config/kivitendo.conf".'));
158
    if (!$config) {
159
      my $locale = Locale->new('en');
160
      $self->mini_error($locale->text('Missing configuration section "authentication/#1" in "config/kivitendo.conf".', $config_name));
161
    }
162

  
163
    if ($module eq 'DB') {
164
      push @{ $self->{authenticators} }, SL::Auth::DB->new($self);
165

  
166
    } elsif ($module eq 'LDAP') {
167
      push @{ $self->{authenticators} }, SL::Auth::LDAP->new($config);
168

  
169
    } else {
170
      my $locale = Locale->new('en');
171
      $self->mini_error($locale->text('Unknown authenticantion module #1 specified in "config/kivitendo.conf".', $module));
172
    }
158 173
  }
159 174

  
160 175
  my $cfg = $self->{DB_config};
......
169 184
    $self->mini_error($locale->text('config/kivitendo.conf: Missing parameters in "authentication/database". Required parameters are "host", "db" and "user".'));
170 185
  }
171 186

  
172
  $self->{authenticator}->verify_config();
187
  $_->verify_config for @{ $self->{authenticators} };
173 188

  
174 189
  $self->{session_timeout} *= 1;
175 190
  $self->{session_timeout}  = 8 * 60 if (!$self->{session_timeout});
......
229 244
    return ERR_PASSWORD;
230 245
  }
231 246

  
232
  my $result = $login ? $self->{authenticator}->authenticate($login, $password) : ERR_USER;
247
  my $result = ERR_USER;
248
  if ($login) {
249
    foreach my $authenticator (@{ $self->{authenticators} }) {
250
      $result = $authenticator->authenticate($login, $password);
251
      last if $result == OK;
252
    }
253
  }
254

  
233 255
  $self->set_session_value(SESSION_KEY_USER_AUTH() => $result, login => $login, client_id => $self->client->{id});
234 256
  return $result;
235 257
}
......
414 436
sub can_change_password {
415 437
  my $self = shift;
416 438

  
417
  return $self->{authenticator}->can_change_password();
439
  return any { $_->can_change_password } @{ $self->{authenticators} };
418 440
}
419 441

  
420 442
sub change_password {
421 443
  my ($self, $login, $new_password) = @_;
422 444

  
423
  my $result = $self->{authenticator}->change_password($login, $new_password);
445
  my $overall_result = OK;
424 446

  
425
  return $result;
447
  foreach my $authenticator (@{ $self->{authenticators} }) {
448
    next unless $authenticator->can_change_password;
449

  
450
    my $result = $authenticator->change_password($login, $new_password);
451
    $overall_result = $result if $result != OK;
452
  }
453

  
454
  return $overall_result;
426 455
}
427 456

  
428 457
sub read_all_users {
SL/Auth/LDAP.pm
32 32

  
33 33
  return $self->{ldap} if $self->{ldap};
34 34

  
35
  my $port      = $cfg->{port} || 389;
36
  $self->{ldap} = Net::LDAP->new($cfg->{host}, 'port' => $port);
35
  my $port = $cfg->{port} || 389;
36
  my $ldap = Net::LDAP->new($cfg->{host}, port => $port, timeout => $cfg->{timeout} || 10);
37 37

  
38
  if (!$self->{ldap}) {
39
    $main::form->error($main::locale->text('The LDAP server "#1:#2" is unreachable. Please check config/kivitendo.conf.', $cfg->{host}, $port));
38
  if (!$ldap) {
39
    $::lxdebug->warn($main::locale->text('The LDAP server "#1:#2" is unreachable. Please check config/kivitendo.conf.', $cfg->{host}, $port));
40
    return undef;
40 41
  }
41 42

  
42 43
  if ($cfg->{tls}) {
43
    my $mesg = $self->{ldap}->start_tls('verify' => 'none');
44
    my $mesg = $ldap->start_tls(verify => $cfg->{verify} // 'require');
44 45
    if ($mesg->is_error()) {
45
      $main::form->error($main::locale->text('The connection to the LDAP server cannot be encrypted (SSL/TLS startup failure). Please check config/kivitendo.conf.'));
46
      $::lxdebug->warn($main::locale->text('The connection to the LDAP server cannot be encrypted (SSL/TLS startup failure). Please check config/kivitendo.conf.'));
47
      return undef;
46 48
    }
47 49
  }
48 50

  
49 51
  if ($cfg->{bind_dn}) {
50
    my $mesg = $self->{ldap}->bind($cfg->{bind_dn}, 'password' => $cfg->{bind_password});
52
    my $mesg = $ldap->bind($cfg->{bind_dn}, 'password' => $cfg->{bind_password});
51 53
    if ($mesg->is_error()) {
52
      $main::form->error($main::locale->text('Binding to the LDAP server as "#1" failed. Please check config/kivitendo.conf.', $cfg->{bind_dn}));
54
      $::lxdebug->warn($main::locale->text('Binding to the LDAP server as "#1" failed. Please check config/kivitendo.conf.', $cfg->{bind_dn}));
55
      return undef;
53 56
    }
54 57
  }
55 58

  
59
  $self->{ldap} = $ldap;
60

  
56 61
  return $self->{ldap};
57 62
}
58 63

  
config/kivitendo.conf.default
4 4
# interface.
5 5
admin_password = admin123
6 6

  
7
# Which module to use for authentication. Valid values are 'DB' and
8
# 'LDAP'.  If 'LDAP' is used then users cannot change their password
9
# via kivitendo.
7
# Which modules to use for authentication. Valid values are 'DB' and
8
# 'LDAP'. You can use multiple modules separated by spaces.
9
#
10
# Multiple LDAP modules with different configurations can be used by
11
# postfixing 'LDAP' with the name of the configuration section to use:
12
# 'LDAP:ldap_fallback' would use the data from
13
# '[authentication/ldap_fallback]'. The name defaults to 'ldap' if it
14
# isn't given.
15
#
16
# Note that the LDAP module doesn't support changing the password.
10 17
module = DB
11 18

  
12 19
# The cookie name can be changed if desired.
......
43 50
# specified.
44 51
#
45 52
# tls:       Activate encryption via TLS
53
# verify:    If 'tls' is used, how to verify the server's certificate.
54
#            Can be one of 'require' or 'none'.
46 55
# attribute: Name of the LDAP attribute containing the user's login name
47 56
# base_dn:   Base DN the LDAP searches start from
48 57
# filter:    An optional LDAP filter specification. The string '<%login%>'
......
51 60
#            If searching the LDAP tree requires user credentials
52 61
#            (e.g. ActiveDirectory) then these two parameters specify
53 62
#            the user name and password to use.
63
# timeout:   Timeout when connecting to the server in seconds.
64
#
65
# You can specify a fallback LDAP server to use in case the main one
66
# isn't reachable by duplicating this whole section as
67
# "[authentication/ldap_fallback]".
68
#
54 69
host          = localhost
55 70
port          = 389
56 71
tls           = 0
......
59 74
filter        =
60 75
bind_dn       =
61 76
bind_password =
77
timeout       = 10
78
verify        = require
62 79

  
63 80
[system]
64 81
# Set language for login and admin forms. Currently "de" (German)
locale/de/all
1907 1907
  'Missing Method!'             => 'Fehlender Voranmeldungszeitraum',
1908 1908
  'Missing Tax Authoritys Preferences' => 'Fehlende Angaben zum Finanzamt!',
1909 1909
  'Missing amount'              => 'Fehlbetrag',
1910
  'Missing configuration section "authentication/#1" in "config/kivitendo.conf".' => 'Fehlender Konfigurationsabschnitt "authentication/#1" in "config/kivitendo.conf".',
1910 1911
  'Missing parameter #1 in call to sub #2.' => 'Fehlender Parameter \'#1\' in Funktionsaufruf \'#2\'.',
1911 1912
  'Missing parameter (at least one of #1) in call to sub #2.' => 'Fehlernder Parameter (mindestens einer aus \'#1\') in Funktionsaufruf \'#2\'.',
1912 1913
  'Missing parameter for WebDAV file copy' => 'Fehlender Parameter für WebDAV Datei kopieren',
......
2018 2019
  'No groups have been created yet.' => 'Es wurden noch keine Gruppen angelegt.',
2019 2020
  'No internal phone extensions have been configured yet.' => 'Es wurden noch keine internen Durchwahlen konfiguriert.',
2020 2021
  'No invoices have been selected.' => 'Es wurden keine Rechnungen ausgewählt.',
2021
  'No or an unknown authenticantion module specified in "config/kivitendo.conf".' => 'Es wurde kein oder ein unbekanntes Authentifizierungsmodul in "config/kivitendo.conf" angegeben.',
2022 2022
  'No part was selected.'       => 'Es wurde kein Artikel ausgewählt',
2023 2023
  'No payment term has been created yet.' => 'Es wurden noch keine Zahlungsbedingungen angelegt.',
2024 2024
  'No picture has been uploaded' => 'Es wurde kein Bild hochgeladen',
......
3711 3711
  'Units that have already been used (e.g. for parts and services or in invoices or warehouse transactions) cannot be changed.' => 'Einheiten, die bereits in Benutzung sind (z.B. bei einer Warendefinition, einer Rechnung oder bei einer Lagerbuchung) können nachträglich nicht mehr verändert werden.',
3712 3712
  'Unknown Category'            => 'Unbekannte Kategorie',
3713 3713
  'Unknown Link'                => 'Unbekannte Verknüpfung',
3714
  'Unknown authenticantion module #1 specified in "config/kivitendo.conf".' => 'Unbekanntes Authentifizierungsmodul #1 angegeben in "config/kivitendo.conf".',
3714 3715
  'Unknown control fields: #1'  => 'Unbekannte Kontrollfelder: #1',
3715 3716
  'Unknown dependency \'%s\'.'  => 'Unbekannte Abhängigkeit \'%s\'.',
3716 3717
  'Unknown module: #1'          => 'Unbekanntes Modul #1',

Auch abrufbar als: Unified diff