1 package SL::Auth::HTTPHeaders;
3 use List::MoreUtils qw(any);
5 use SL::Auth::Constants qw(:all);
9 my @required_config_options = qw(secret_header secret user_header client_id_header);
14 $self->{config} = shift;
25 sub _env_var_for_header {
29 return $ENV{'HTTP_' . uc($header)};
33 my ($self, $type) = @_;
35 my $secret = _env_var_for_header($self->{config}->{secret_header}) // '';
36 if ($secret ne $self->{config}->{secret}) {
37 $::lxdebug->message(LXDebug->DEBUG2(), "HTTPHeaders ${type}: bad secret sent by upstream server: $secret");
41 my $client_id = _env_var_for_header($self->{config}->{client_id_header});
43 $::lxdebug->message(LXDebug->DEBUG2(), "HTTPHeaders ${type}: no client ID header found");
44 return (ERR_PASSWORD);
47 # $::auth->set_client();
49 my $user = _env_var_for_header($self->{config}->{user_header});
51 $::lxdebug->message(LXDebug->DEBUG2(), "HTTPHeaders ${type}: no user name header found");
52 return (ERR_PASSWORD);
55 $::lxdebug->message(LXDebug->DEBUG2(), "HTTPHeaders ${type}: OK client $client_id user $user");
57 return (OK, $client_id, $user);
63 my ($status, $client, $login) = $self->_authenticate('authenticate');
68 sub can_change_password {
72 sub requires_cleartext_password {
82 my $cfg = $self->{config};
85 die 'config/kivitendo.conf: Key "authentication/http_headers" is missing.';
88 foreach (@required_config_options) {
90 die 'config/kivitendo.conf: Missing parameter in "authentication/http_headers": ' . $_;
100 SL::Auth::HTTPHeaders - Automatically log in users based on headers
101 sent by upstream servers
105 This module implements two modes for automatic log in for users:
109 =item HTTP Basic Authentication
111 =item passing user name & client ID via arbitrary headers
115 The module must be enabled in the configuration file by setting
116 C<authentication.module=HTTPHeaders>. It is then configured by the
117 sections C<authentication/http_basic> & C<authentication/http_headers>.
119 =head1 SUPPORTED AUTHENTICATION METHODS
121 =head2 User name & client ID in HTTP headers
123 Must be enabled by setting
124 C<authentication/http_headers.enabled=1>. If enabled, it relies on
125 upstream servers (web server, proxy server) doing the authentication
126 with SSO solutions like Authelia & Authentik. These solutions must
127 then send the user name of the authenticated user in an HTTP header &
128 the desired client ID in another header.
130 In order to ensure no malicious third party can simply set these
131 header values, a shared secret must be configured in the configuration
132 file & sent along in a third header field.
134 The names of all three headers as well as the shared secret must be
135 set in the configuration file's C<authentication/http_headers>
138 This mode is mutually exclusive with the HTTP Basic Authentication
141 =head2 HTTP Basic Authentication (RFC 7617)
143 Must be enabled by setting C<authentication/http_basic.enabled=1>. If
144 enabled, it relies on the web server doing the authentication for it &
145 passing the result in the C<Authorization> header, which turns into e
146 environment variable C<HTTP_AUTHORIZATION> according to the CGI
149 This mode only supports using the default client as no way to pass the
150 desired client ID has been implemented yet.
152 This mode is mutually exclusive with the "User name & client ID in
153 HTTP headers" mode mentioned above.
157 Moritz Bunkus E<lt>m.bunkus@linet.deE<gt>