Symfony 安全例外:$opsLimit必须为 3 或更大



我的Symfony 4.4.9应用程序运行良好,我已经做了一些简单的修复并重建了应用程序(Docker(,我不知道为什么我不能再登录管理面板:

request.CRITICAL: Uncaught PHP Exception InvalidArgumentException: 
"$opsLimit must be 3 or greater." 
at /app/vendor/symfony/security-core/Encoder/NativePasswordEncoder.php 
line 40 {
"exception":"[object] (InvalidArgumentException(code: 0): 
$opsLimit must be 3 or greater. 
at /app/vendor/symfony/security-core/Encoder/NativePasswordEncoder.php:40)"
} []

我不知道这是什么意思!我用谷歌搜索了一下,但什么也没找到,但是,在开发环境中一切都很好

知道吗?谢谢:)

我能够在本地开发环境中重现该错误。这是我的安全.yaml :

security:
encoders:
AppEntityUtilisateur:
algorithm: argon2i
memory_cost: 16384
time_cost: 2
threads: 4

我已将time_cost更改为3,现在可以:)

首先查看第 40 行的/app/vendor/symfony/security-core/Encoder/NativePasswordEncoder.php。记录整个堆栈跟踪,您将看到错误是什么。这是实际文件

<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SymfonyComponentSecurityCoreEncoder;
use SymfonyComponentSecurityCoreExceptionBadCredentialsException;
/**
* Hashes passwords using password_hash().
*
* @author Elnur Abdurrakhimov <elnur@elnur.pro>
* @author Terje Bråten <terje@braten.be>
* @author Nicolas Grekas <p@tchwork.com>
*/
final class NativePasswordEncoder implements PasswordEncoderInterface, SelfSaltingEncoderInterface
{
private const MAX_PASSWORD_LENGTH = 4096;
private $algo = PASSWORD_BCRYPT;
private $options;
/**
* @param string|null $algo An algorithm supported by password_hash() or null to use the stronger available algorithm
*/
public function __construct(int $opsLimit = null, int $memLimit = null, int $cost = null, string $algo = null)
{
$cost = $cost ?? 13;
$opsLimit = $opsLimit ?? max(4, defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE') ? SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE : 4);
$memLimit = $memLimit ?? max(64 * 1024 * 1024, defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 1024);
if (3 > $opsLimit) {
throw new InvalidArgumentException('$opsLimit must be 3 or greater.');
}
if (10 * 1024 > $memLimit) {
throw new InvalidArgumentException('$memLimit must be 10k or greater.');
}
if ($cost < 4 || 31 < $cost) {
throw new InvalidArgumentException('$cost must be in the range of 4-31.');
}
$algos = [1 => PASSWORD_BCRYPT, '2y' => PASSWORD_BCRYPT];
if (defined('PASSWORD_ARGON2I')) {
$this->algo = $algos[2] = $algos['argon2i'] = (string) PASSWORD_ARGON2I;
}
if (defined('PASSWORD_ARGON2ID')) {
$this->algo = $algos[3] = $algos['argon2id'] = (string) PASSWORD_ARGON2ID;
}
if (null !== $algo) {
$this->algo = $algos[$algo] ?? $algo;
}
$this->options = [
'cost' => $cost,
'time_cost' => $opsLimit,
'memory_cost' => $memLimit >> 10,
'threads' => 1,
];
}
/**
* {@inheritdoc}
*/
public function encodePassword(string $raw, ?string $salt): string
{
if (strlen($raw) > self::MAX_PASSWORD_LENGTH || ((string) PASSWORD_BCRYPT === $this->algo && 72 < strlen($raw))) {
throw new BadCredentialsException('Invalid password.');
}
// Ignore $salt, the auto-generated one is always the best
return password_hash($raw, $this->algo, $this->options);
}
/**
* {@inheritdoc}
*/
public function isPasswordValid(string $encoded, string $raw, ?string $salt): bool
{
if ('' === $raw) {
return false;
}
if (strlen($raw) > self::MAX_PASSWORD_LENGTH) {
return false;
}
if (0 !== strpos($encoded, '$argon')) {
// BCrypt encodes only the first 72 chars
return (72 >= strlen($raw) || 0 !== strpos($encoded, '$2')) && password_verify($raw, $encoded);
}
if (extension_loaded('sodium') && version_compare(SODIUM_LIBRARY_VERSION, '1.0.14', '>=')) {
return sodium_crypto_pwhash_str_verify($encoded, $raw);
}
if (extension_loaded('libsodium') && version_compare(phpversion('libsodium'), '1.0.14', '>=')) {
return Sodiumcrypto_pwhash_str_verify($encoded, $raw);
}
return password_verify($raw, $encoded);
}
/**
* {@inheritdoc}
*/
public function needsRehash(string $encoded): bool
{
return password_needs_rehash($encoded, $this->algo, $this->options);
}
}

这是它的相关部分:

$opsLimit = $opsLimit ?? max(4, defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE') ? SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE : 4);
$memLimit = $memLimit ?? max(64 * 1024 * 1024, defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 1024);
if (3 > $opsLimit) {
throw new InvalidArgumentException('$opsLimit must be 3 or greater.');
}

基本上你已经定义了SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE并且小于或等于三。在您的文件中搜索此文本的所有匹配项并找到罪魁祸首。

最新更新