Skip to content

Commit fb8d6ee

Browse files
committed
Provide mixed authentication with basic and LDAP
1 parent 054a7f8 commit fb8d6ee

3 files changed

Lines changed: 105 additions & 1 deletion

File tree

config/services.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ services:
4545
$LDAPCertificateCheckingStrategy: "%env(LDAP_CERTIFICATE_CHECKING_STRATEGY)%"
4646
$autoCreate: "%env(bool:LDAP_AUTH_USER_AUTOCREATE)%"
4747

48+
App\Services\LDAPFallbackAuth:
49+
arguments:
50+
$LDAPAuthUrl: "%env(LDAP_AUTH_URL)%"
51+
$LDAPDnPattern: "%env(LDAP_DN_PATTERN)%"
52+
$LDAPMailAttribute: "%env(LDAP_MAIL_ATTRIBUTE)%"
53+
$LDAPCertificateCheckingStrategy: "%env(LDAP_CERTIFICATE_CHECKING_STRATEGY)%"
54+
$autoCreate: "%env(bool:LDAP_AUTH_USER_AUTOCREATE)%"
55+
$whichFirst: "%env(AUTH_WHICH_PROVIDER_FIRST)%"
56+
4857
# controllers are imported separately to make sure services can be injected
4958
# as action arguments even if you don't extend any base controller class
5059
App\Controller\:

src/Controller/DAVController.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use App\Services\BirthdayService;
1212
use App\Services\IMAPAuth;
1313
use App\Services\LDAPAuth;
14+
use App\Services\LDAPFallbackAuth;
1415
use Doctrine\ORM\EntityManagerInterface;
1516
use PDO;
1617
use Psr\Log\LoggerInterface;
@@ -27,6 +28,7 @@ class DAVController extends AbstractController
2728
public const AUTH_BASIC = 'Basic';
2829
public const AUTH_IMAP = 'IMAP';
2930
public const AUTH_LDAP = 'LDAP';
31+
public const AUTH_LDAP_AND_BASIC = 'BasicAndLDAP';
3032

3133
/**
3234
* Is CalDAV enabled?
@@ -135,6 +137,13 @@ class DAVController extends AbstractController
135137
*/
136138
protected $LDAPAuthBackend;
137139

140+
/**
141+
* LDAP with Fallback Auth Backend class.
142+
*
143+
* @var LDAPFallbackAuth
144+
*/
145+
protected $LDAPFallbackAuthBackend;
146+
138147
/**
139148
* Logger for exceptions.
140149
*
@@ -149,7 +158,7 @@ class DAVController extends AbstractController
149158
*/
150159
protected $server;
151160

152-
public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend, IMAPAuth $IMAPAuthBackend, LDAPAuth $LDAPAuthBackend, UrlGeneratorInterface $router, EntityManagerInterface $entityManager, LoggerInterface $logger, BirthdayService $birthdayService, string $publicDir, bool $calDAVEnabled = true, bool $cardDAVEnabled = true, bool $webDAVEnabled = false, bool $publicCalendarsEnabled = true, ?string $inviteAddress = null, ?string $authMethod = null, ?string $authRealm = null, ?string $webdavPublicDir = null, ?string $webdavHomesDir = null, ?string $webdavTmpDir = null)
161+
public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend, IMAPAuth $IMAPAuthBackend, LDAPAuth $LDAPAuthBackend, LDAPFallbackAuth $LDAPFallbackAuthBackend, UrlGeneratorInterface $router, EntityManagerInterface $entityManager, LoggerInterface $logger, BirthdayService $birthdayService, string $publicDir, bool $calDAVEnabled = true, bool $cardDAVEnabled = true, bool $webDAVEnabled = false, bool $publicCalendarsEnabled = true, ?string $inviteAddress = null, ?string $authMethod = null, ?string $authRealm = null, ?string $webdavPublicDir = null, ?string $webdavHomesDir = null, ?string $webdavTmpDir = null)
153162
{
154163
$this->publicDir = $publicDir;
155164

@@ -172,6 +181,7 @@ public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend
172181
$this->basicAuthBackend = $basicAuthBackend;
173182
$this->IMAPAuthBackend = $IMAPAuthBackend;
174183
$this->LDAPAuthBackend = $LDAPAuthBackend;
184+
$this->LDAPFallbackAuthBackend = $LDAPFallbackAuthBackend;
175185

176186
$this->initServer($authMethod, $authRealm);
177187
$this->initExceptionListener();
@@ -200,6 +210,9 @@ private function initServer(string $authMethod, string $authRealm = User::DEFAUL
200210
case self::AUTH_LDAP:
201211
$authBackend = $this->LDAPAuthBackend;
202212
break;
213+
case self::AUTH_LDAP_AND_BASIC:
214+
$authBackend = $this->LDAPFallbackAuthBackend;
215+
break;
203216
case self::AUTH_BASIC:
204217
default:
205218
$authBackend = $this->basicAuthBackend;

src/Services/LDAPFallbackAuth.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace App\Services;
4+
5+
use App\Entity\User;
6+
use App\Services\BasicAuth;
7+
use App\Services\LDAPAuth;
8+
use Doctrine\Persistence\ManagerRegistry;
9+
use Sabre\DAV\Auth\Backend\AbstractBasic;
10+
11+
final class LDAPFallbackAuth extends AbstractBasic
12+
{
13+
14+
public const PROVIDER_BASIC = 'Basic';
15+
public const PROVIDER_LDAP = 'LDAP';
16+
17+
/**
18+
* LDAP authenticator.
19+
*
20+
* @var App\Services\LDAPAuth
21+
*/
22+
private $LDAPAuth;
23+
24+
/**
25+
* Basic authenticator.
26+
*
27+
* @var App\Services\BasicAuth
28+
*/
29+
private $BasicAuth;
30+
31+
/**
32+
* Configure which authenticator to check first.
33+
*
34+
* Either 'LDAP' or 'Basic'
35+
*
36+
* @var string
37+
*
38+
*/
39+
private $whichFirst;
40+
41+
/**
42+
* Creates the backend object.
43+
*/
44+
public function __construct(ManagerRegistry $doctrine, Utils $utils, string $LDAPAuthUrl, string $LDAPDnPattern, ?string $LDAPMailAttribute, bool $autoCreate, ?string $LDAPCertificateCheckingStrategy, ?string $whichFirst)
45+
{
46+
47+
$this->LDAPAuth = new LDAPAuth($doctrine, $utils, $LDAPAuthUrl, $LDAPDnPattern, $LDAPMailAttribute ?? 'mail', $autoCreate, $LDAPCertificateCheckingStrategy ?? 'try' );
48+
$this->BasicAuth = new BasicAuth($doctrine, $utils);
49+
$this->whichFirst = $whichFirst ?? PROVIDER_BASIC;
50+
51+
$this->doctrine = $doctrine;
52+
$this->utils = $utils;
53+
}
54+
55+
/**
56+
* Validates a username and password by trying to authenticate against LDAP.
57+
*
58+
* @param string $username
59+
* @param string $password
60+
*/
61+
protected function validateUserPass($username, $password): bool
62+
{
63+
/*
64+
* Use the backends.
65+
*/
66+
switch ($this->whichFirst) {
67+
case self::PROVIDER_BASIC:
68+
if(!$this->BasicAuth->validateUserPass($username, $password)){
69+
return $this->LDAPAuth->validateUserPass($username, $password);
70+
}else{
71+
return true;
72+
}
73+
case self::PROVIDER_LDAP:
74+
if(!$this->LDAPAuth->validateUserPass($username, $password)){
75+
return $this->BasicAuth->validateUserPass($username, $password);
76+
}else{
77+
return true;
78+
}
79+
}
80+
return false;
81+
}
82+
}

0 commit comments

Comments
 (0)