- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/user.php
- Класс: CAllUser
- Вызов: CAllUser::Login
public function Login($login, $password, $remember = 'N', $password_original = 'Y')
{
global $APPLICATION;
$result_message = true;
$user_id = 0;
$context = new AuthenticationContext();
$arParams = [
"LOGIN" => &$login,
"PASSWORD" => &$password,
"REMEMBER" => &$remember,
"PASSWORD_ORIGINAL" => &$password_original,
];
unset(static::$kernelSession["SESS_OPERATIONS"]);
$APPLICATION->SetNeedCAPTHA(false);
$bOk = true;
$APPLICATION->ResetException();
foreach (GetModuleEvents('main', 'OnBeforeUserLogin', true) as $arEvent)
{
if (ExecuteModuleEventEx($arEvent, [&$arParams]) === false)
{
if ($err = $APPLICATION->GetException())
{
$result_message = ["MESSAGE" => $err->GetString() . "
", "TYPE" => "ERROR"];
}
else
{
$APPLICATION->ThrowException("Unknown login error");
$result_message = ["MESSAGE" => "Unknown login error" . "
", "TYPE" => "ERROR"];
}
$bOk = false;
break;
}
}
if ($bOk)
{
//external authentication
foreach (GetModuleEvents('main', 'OnUserLoginExternal', true) as $arEvent)
{
$user_id = ExecuteModuleEventEx($arEvent, [&$arParams]);
if (isset($arParams["RESULT_MESSAGE"]))
{
$result_message = $arParams["RESULT_MESSAGE"];
}
if ($user_id > 0)
{
break;
}
}
if ($user_id <= 0)
{
//internal authentication OR application password for external user
$user_id = static::LoginInternal($arParams, $result_message, $context);
if ($user_id <= 0)
{
//no user found by login - try to find an external user
foreach (GetModuleEvents('main', 'OnFindExternalUser', true) as $arEvent)
{
if (($external_user_id = intval(ExecuteModuleEventEx($arEvent, [$arParams["LOGIN"]]))) > 0)
{
//external user authentication
//let's try to find application password for the external user
if (($appPassword = ApplicationPasswordTable::findPassword($external_user_id, $arParams["PASSWORD"], ($arParams["PASSWORD_ORIGINAL"] == 'Y'))) !== false)
{
//bingo, the user has the application password
$user_id = $external_user_id;
$result_message = true;
$context
->setApplicationId($appPassword["APPLICATION_ID"])
->setApplicationPasswordId($appPassword["ID"])
;
}
break;
}
}
}
}
}
// All except Admin
if ($user_id > 1 && (!isset($arParams["CONTROLLER_ADMIN"]) || $arParams["CONTROLLER_ADMIN"] !== 'Y'))
{
if (!static::CheckUsersCount($user_id))
{
$user_id = 0;
$APPLICATION->ThrowException(GetMessage("LIMIT_USERS_COUNT"));
$result_message = [
"MESSAGE" => GetMessage("LIMIT_USERS_COUNT") . "
",
"TYPE" => "ERROR",
];
}
}
$arParams["USER_ID"] = $user_id;
$doAuthorize = true;
if ($user_id > 0)
{
if ($context->getApplicationId() === null && CModule::IncludeModule("security"))
{
/*
MFA can allow or disallow authorization.
Allowed if:
- OTP is not active for the user;
- correct "OTP" in the $arParams (filled by the OnBeforeUserLogin event handler).
Disallowed if:
- OTP is not provided;
- OTP is not correct.
When authorization is disallowed the OTP form will be shown on the next hit.
Note: there is no MFA check for an application password.
*/
$arParams["CAPTCHA_WORD"] = $_REQUEST["captcha_word"] ?? '';
$arParams["CAPTCHA_SID"] = $_REQUEST["captcha_sid"] ?? '';
$doAuthorize = BitrixSecurityMfaOtp::verifyUser($arParams);
}
if ($doAuthorize)
{
$context->setUserId($user_id);
$this->Authorize($context, ($arParams["REMEMBER"] == 'Y'));
}
else
{
$result_message = false;
}
if ($context->getApplicationId() === null && $arParams["LOGIN"] != '')
{
//the cookie is for authentication forms mostly, does not make sense for applications
$cookie = new MainWebCookie("LOGIN", $arParams["LOGIN"], time() + 60 * 60 * 24 * 30 * 12);
MainContext::getCurrent()->getResponse()->addCookie($cookie);
}
}
else
{
if (CModule::IncludeModule("security"))
{
//disable OTP from if login was incorrect
BitrixSecurityMfaOtp::setDeferredParams(null);
}
}
$arParams["RESULT_MESSAGE"] = $result_message;
$APPLICATION->ResetException();
foreach (GetModuleEvents('main', 'OnAfterUserLogin', true) as $arEvent)
{
ExecuteModuleEventEx($arEvent, [&$arParams]);
}
if ($doAuthorize && $result_message !== true && (Option::get('main', 'event_log_login_fail', 'N') === 'Y'))
{
CEventLog::Log('SECURITY', 'USER_LOGIN', 'main', $login, $result_message['MESSAGE']);
}
return $arParams["RESULT_MESSAGE"];
}