Php Symfony4自定义密码编码器
我正在升级一个旧的应用程序,以便在后端使用Symfony(v4),我一直在尝试让身份验证正常工作。我的数据库为用户存储哈希密码和盐,密码使用Php Symfony4自定义密码编码器,php,symfony,authentication,symfony4,lexikjwtauthbundle,Php,Symfony,Authentication,Symfony4,Lexikjwtauthbundle,我正在升级一个旧的应用程序,以便在后端使用Symfony(v4),我一直在尝试让身份验证正常工作。我的数据库为用户存储哈希密码和盐,密码使用cryptphp函数。我还使用lexik JWT包试图将令牌返回到前端 我无法从symfony/lexik获得除“错误凭据”之外的响应 我认为我的问题根源在于编码器部分,我尝试实现一个自定义密码编码器,因为crypt根据php文档使用了一个修改过的DES算法,并且在我的安全性中简单地使用了以下内容。yaml不起作用 encoders: App\Entity\
crypt
php函数。我还使用lexik JWT包试图将令牌返回到前端
我无法从symfony/lexik获得除“错误凭据”之外的响应
我认为我的问题根源在于编码器部分,我尝试实现一个自定义密码编码器,因为crypt根据php文档使用了一个修改过的DES算法,并且在我的安全性中简单地使用了以下内容。yaml不起作用
encoders:
App\Entity\DB_1\User:
algorithm: DES
这是我的安全措施
security.yaml
security:
encoders:
App\Entity\DB_1\User:
id: 'App\Security\MyPasswordEncoder'
providers:
entity_provider:
entity:
class: App\Entity\MetallicBonds\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
json_login:
check_path: /login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
register:
pattern: ^/register
stateless: true
anonymous: true
api:
pattern: ^/test
stateless: true
anonymous: false
provider: entity_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/test, roles: IS_AUTHENTICATED_FULLY }
和我的自定义密码编码器MyPasswordEncoder.php
namespace App\Security;
use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
class MyPasswordEncoder extends BasePasswordEncoder implements
PasswordEncoderInterface
{
private $ignorePasswordCase;
public function __construct($ignorePasswordCase = false)
{
$this->ignorePasswordCase = $ignorePasswordCase;
}
public function encodePassword($raw, $salt)
{
// TODO: Implement encodePassword() method.
return crypt($raw,$salt);
}
public function isPasswordValid($encoded, $raw, $salt)
{
// TODO: Implement isPasswordValid() method.
if ($this->isPasswordTooLong($raw)) {
return false;
}
try {
$pass2 = $this->encodePassword($raw, $salt);
} catch (BadCredentialsException $e) {
return false;
}
if (!$this->ignorePasswordCase) {
return $this->comparePasswords($encoded, $pass2);
}
return $this->comparePasswords(strtolower($encoded), strtolower($pass2));
}
}
我想使用当前存储的密码,至少目前是这样,因此,对于最终用户来说,从旧系统到新系统的更改将是顺利的。是否有人成功地将自定义密码编码器与Symfony 4配合使用
我应该注意,当我在MyPasswordEncoder.php中放置xdebug断点时,它不会停止应用程序,是否需要在其他地方注册该类,以便Symfony使用它?这是我的security.yaml
安全性:
编码器:
应用程序\实体\用户:
id:'App\Security\Encoder\MyCustomPasswordEncoder'
这是我的密码
namespace App\Security\Encoder;
use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
class MyCustomPasswordEncoder extends BasePasswordEncoder
{
private $algorithm;
private $encodeHashAsBase64;
private $iterations;
/**
* @param string $algorithm The digest algorithm to use
* @param bool $encodeHashAsBase64 Whether to base64 encode the password hash
* @param int $iterations The number of iterations to use to stretch the password hash
*/
public function __construct(string $algorithm = 'sha1', bool $encodeHashAsBase64 = false, int $iterations = 0)
{
$this->algorithm = $algorithm;
$this->encodeHashAsBase64 = $encodeHashAsBase64;
$this->iterations = $iterations;
}
/**
* {@inheritdoc}
*/
public function encodePassword($raw, $salt)
{
if ($this->isPasswordTooLong($raw)) {
throw new BadCredentialsException('Invalid password.');
}
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
//$salted = $this->mergePasswordAndSalt($raw, $salt);
$salted = $salt.$raw;
$digest = hash($this->algorithm, $salted, true);
// "stretch" hash
for ($i = 1; $i < $this->iterations; ++$i) {
$digest = hash($this->algorithm, $digest.$salted, true);
}
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
/**
* {@inheritdoc}
*/
public function isPasswordValid($encoded, $raw, $salt)
{
return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
namespace-App\Security\Encoder;
使用Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
类MyCustomPasswordEncoder扩展了BasePasswordEncoder
{
私有$算法;
私人$ASBASE64;
私有$迭代;
/**
*@param string$算法要使用的摘要算法
*@param bool$encodeHashAsBase64是否对密码哈希进行base64编码
*@param int$iterations用于拉伸密码哈希的迭代次数
*/
公共函数构造(字符串$algorithm='sha1',bool$encodehashasbasbase64=false,int$iterations=0)
{
$this->algorithm=$algorithm;
$this->encodeHashAsBase64=$encodeHashAsBase64;
$this->iterations=$iterations;
}
/**
*{@inheritardoc}
*/
公共函数密码($raw,$salt)
{
如果($this->isPasswordTooLong($raw)){
抛出新的BadCredentialsException(“无效密码”);
}
if(!in_数组($this->algorithm,hash_algos(),true)){
抛出new\LogicException(sprintf('不支持算法“%s”。,$this->algorithm));
}
//$salted=$this->mergePasswordAndSalt($raw,$salt);
$salted=$salt.$raw;
$digest=hash($this->algorithm,$salted,true);
//“拉伸”散列
对于($i=1;$i<$this->iterations;++$i){
$digest=hash($this->algorithm,$digest.$salted,true);
}
返回$this->encodeHashAsBase64?base64_encode($digest):bin2hex($digest);
}
/**
*{@inheritardoc}
*/
公共函数isPasswordValid($encoded、$raw、$salt)
{
return!$this->isPasswordTooLong($raw)和&$this->comparePasswords($encoded,$this->encodePassword($raw,$salt));
}
}
代码正确运行。旧代码是symfony 1.4。严格地说是猜测,但我认为您的登录防火墙需要一个提供者条目。
security.yaml
文件的缩进是否如StackOverflow上所示?编码器
、提供者
和防火墙
键应该是安全
键的子项,这里似乎不是这样。缩进是正确的,只是没有正确复制并粘贴到文本框中。我做了类似的操作,调用了自定义类的ctor,但没有调用“isPasswordValid”功能。你知道为什么吗?我正在尝试使用JWT包登录。