Php Symfony2创建自定义AccountStatusException

Php Symfony2创建自定义AccountStatusException,php,symfony,Php,Symfony,我想更改在使用UserCheckerclass进行身份验证之前如何检查用户的默认Symfony逻辑 它有一个方法checkPreAuth,在对用户进行身份验证之前进行一些检查: public function checkPreAuth(UserInterface $user) { if (!$user instanceof AdvancedUserInterface) { return; } if (!$user->isAccountNonLock

我想更改在使用
UserChecker
class进行身份验证之前如何检查用户的默认Symfony逻辑

它有一个方法
checkPreAuth
,在对用户进行身份验证之前进行一些检查:

public function checkPreAuth(UserInterface $user)
{
    if (!$user instanceof AdvancedUserInterface) {
        return;
    }

    if (!$user->isAccountNonLocked()) {
        $ex = new LockedException('User account is locked.');
        $ex->setUser($user);
        throw $ex;
    }

    if (!$user->isEnabled()) {
        $ex = new DisabledException('User account is disabled.');
        $ex->setUser($user);
        throw $ex;
    }

    if (!$user->isAccountNonExpired()) {
        $ex = new AccountExpiredException('User account has expired.');
        $ex->setUser($user);
        throw $ex;
    }
}
我想用我自己的
BannedException
替换默认的
LockedException
,因为我的用户实体包含一些额外的属性,例如
bannedUntil
banReason
,所以如果授权失败,用户可以看到禁令到期的日期和锁定的原因

我已为此创建了新的异常:

namespace Eugenics\SiteBundle\Exception;

use Symfony\Component\Security\Core\Exception\AccountStatusException;

/**
 * Class BannedException.
 */
class BannedException extends AccountStatusException
{
    /**
     * {@inheritdoc}
     */
    public function getMessageKey()
    {
        $user = $this->getUser();
        $bannedUntil = $user->getBannedUntil()->format('Y-m-d H:i:s');
        $banReason = $user->getBanReason();

        return 'You are banned until ' . $bannedUntil . '. Reason: ' . $banReason;
    }
}
问题是继承的方法
getUser()
没有获得用户实体的完整副本,它只是由标准的
AdvancedUserInterface
属性(如用户名、密码等)填充,而不是
bannedUntil
banReason
,它们是空的

最终我看到的是

“你被禁止,直到。原因:”

下面是从
getMessageKey
方法内部转储的
$user
变量:

object(stdClass)#634 (28) { ["__CLASS__"]=> string(30) "Eugenics\SiteBundle\Entity\User" ["comments"]=> NULL ["id"]=> int(5) ["username"]=> string(8) "eugenics" ["email"]=> string(21) "email@example.com" ["salt"]=> string(31) "9lcjfix8eyw4scg0gkk000k4socgcoo" ["password"]=> string(60) "$2y$12$9lcjfix8eyw4scg0gkk00u79ox.0Uc.XtusBoeDFTgRUvKMi9J/FO" ["plainPassword"]=> NULL ["registeredAt"]=> NULL ["lastLoginAt"]=> NULL ["confirmationToken"]=> NULL ["passwordRequestedAt"]=> NULL ["banned"]=> bool(true) ["bannedUntil"]=> NULL ["bannedBy"]=> NULL ["banReason"]=> NULL ["firstName"]=> NULL ["lastName"]=> NULL ["birthdate"]=> NULL ["gender"]=> NULL ["photoUrl"]=> NULL ["photoPreviewUrl"]=> NULL ["confirmed"]=> NULL ["status"]=> NULL ["rating"]=> NULL ["private"]=> NULL ["lastActivityAt"]=> NULL }
但是当我直接从
checkPreAuth()
中转储
$user
对象时,它显示所有属性都已正确填充


是否有可能通过这种方式实现所需的功能?非常感谢您的帮助。

难道->format()不会引发空异常吗?如果$user->getBannedUtil()返回null,则格式将引发异常。确实如此,getBannedUntil()和getBanReason()都返回null,但如果我从checkPreAuth()调用它们,则效果非常好。我不明白为什么getUser()在从AccountStatusException调用时不返回完整的用户对象。有趣的是,从checkPreAuth()转储$ex->getUser()会显示完全填充的用户对象,但从AccountStatusException对$this->getUser()执行相同的操作不会。