mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-09-04 10:14:13 +08:00
Add ldap login fallback to native login
- Allow falling back to native login if ldap fails - Read configuration to enable / disable the fallback
This commit is contained in:
parent
db6afc52fc
commit
8c669180c5
2 changed files with 120 additions and 0 deletions
|
@ -147,6 +147,14 @@ services:
|
|||
- !abstract options
|
||||
- '@?property_accessor'
|
||||
|
||||
security.listener.json_login_ldap.main:
|
||||
class: App\Security\Ldap\AppCheckLdapCredentialsListener
|
||||
tags:
|
||||
- name: 'kernel.event_subscriber'
|
||||
dispatcher: security.event_dispatcher.main
|
||||
arguments:
|
||||
- '@security.ldap_locator'
|
||||
|
||||
App\Security\LegacySessionLogoutHandler:
|
||||
tags:
|
||||
- name: 'kernel.event_listener'
|
||||
|
|
112
core/backend/Security/Ldap/AppCheckLdapCredentialsListener.php
Normal file
112
core/backend/Security/Ldap/AppCheckLdapCredentialsListener.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SalesAgility Ltd.
|
||||
* Copyright (C) 2022 SalesAgility Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License version 3 as published by the
|
||||
* Free Software Foundation with the addition of the following permission added
|
||||
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||||
* IN WHICH THE COPYRIGHT IS OWNED BY SALESAGILITY, SALESAGILITY DISCLAIMS THE
|
||||
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||||
* version 3, these Appropriate Legal Notices must retain the display of the
|
||||
* "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
|
||||
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
namespace App\Security\Ldap;
|
||||
|
||||
use App\Module\Users\Entity\User;
|
||||
use Symfony\Component\Ldap\Security\CheckLdapCredentialsListener;
|
||||
use Symfony\Component\Ldap\Security\LdapBadge;
|
||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
|
||||
use Symfony\Component\Security\Http\Event\CheckPassportEvent;
|
||||
|
||||
class AppCheckLdapCredentialsListener extends CheckLdapCredentialsListener
|
||||
{
|
||||
|
||||
public function onCheckPassport(CheckPassportEvent $event): void
|
||||
{
|
||||
$passport = $event->getPassport();
|
||||
if (!$passport->hasBadge(LdapBadge::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var LdapBadge $ldapBadge */
|
||||
$ldapBadge = $passport->getBadge(LdapBadge::class);
|
||||
if ($ldapBadge->isResolved()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var PasswordCredentials $passwordCredentials */
|
||||
$passwordCredentials = $passport->getBadge(PasswordCredentials::class);
|
||||
|
||||
$presentedPassword = $passwordCredentials->getPassword();
|
||||
if (empty($presentedPassword)) {
|
||||
throw new BadCredentialsException('The presented password cannot be empty.');
|
||||
}
|
||||
|
||||
try {
|
||||
parent::onCheckPassport($event);
|
||||
} catch (BadCredentialsException $e) {
|
||||
$externalAuthOnly = $this->getExternalAuthOnly($passport);
|
||||
|
||||
if (!empty($externalAuthOnly)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$ldapBadge->markResolved();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PassportInterface $passport
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getExternalAuthOnly(PassportInterface $passport): ?string
|
||||
{
|
||||
$user = $this->getUser($passport);
|
||||
|
||||
if ($user === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $user->getExternalAuthOnly();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PassportInterface $passport
|
||||
* @return User|null
|
||||
*/
|
||||
protected function getUser(PassportInterface $passport): ?User
|
||||
{
|
||||
/** @var UserBadge $userBadge */
|
||||
$userBadge = $passport->getBadge(UserBadge::class);
|
||||
|
||||
if ($userBadge === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = $userBadge->getUser();
|
||||
|
||||
if ($user instanceof User) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue