douqin3245 2014-07-17 15:46
浏览 38

Symfony2登录坏证书自定义处理程序/类/提供程序

I'm having trouble using a custom user provider with my custom user class. As highlighted in the log below, I believe the problem exists somewhere in my handler (of course, custom). It doesn't appear to be grabbing the email address (used for authentication: system_user_email_address).

app/config/dev.log

[2014-07-17 09:48:42] request.INFO: Matched route "login_check" (parameters: "_route": "login_check") [] []
[2014-07-17 09:48:42] security.DEBUG: Read SecurityContext from the session [] []
[2014-07-17 09:48:42] security.DEBUG: Reloading user from user provider. [] []
[2014-07-17 09:48:42] doctrine.DEBUG: SELECT t0.system_user_id AS system_user_id1, t0.first_name AS first_name2, t0.last_name AS last_name3, t0.enabled AS enabled4, t0.salt AS salt5, t0.password AS password6, t0.last_login AS last_login7, t0.locked AS locked8, t0.expired AS expired9, t0.expires_at AS expires_at10, t0.confirmation_token AS confirmation_token11, t0.password_requested_at AS password_requested_at12, t0.credentials_expired AS credentials_expired13, t0.credentials_expire_at AS credentials_expire_at14, t0.customer_id AS customer_id15, t0.system_user_phone_number_id AS system_user_phone_number_id16, t0.system_user_email_address_id AS system_user_email_address_id17 FROM system_user t0 WHERE t0.system_user_id = ? [16] []
[2014-07-17 09:48:42] security.DEBUG: Username "" was reloaded from user provider. [] []
[2014-07-17 09:48:42] doctrine.DEBUG: SELECT s0_.system_user_id AS system_user_id0, s0_.first_name AS first_name1, s0_.last_name AS last_name2, s0_.enabled AS enabled3, s0_.salt AS salt4, s0_.password AS password5, s0_.last_login AS last_login6, s0_.locked AS locked7, s0_.expired AS expired8, s0_.expires_at AS expires_at9, s0_.confirmation_token AS confirmation_token10, s0_.password_requested_at AS password_requested_at11, s0_.credentials_expired AS credentials_expired12, s0_.credentials_expire_at AS credentials_expire_at13, s0_.customer_id AS customer_id14, s0_.system_user_phone_number_id AS system_user_phone_number_id15, s0_.system_user_email_address_id AS system_user_email_address_id16 FROM system_user s0_ WHERE s0_.system_user_email_address_id = ? **["NONE_PROVIDED"]** []
[2014-07-17 09:48:42] security.INFO: Authentication request failed: Bad credentials [] []

I'm getting a response correctly from the SystemUserRepository class:

{"success":false,"message":"Bad credentials"}

I have been through the other "Bad Credential" posts, and double checked the problems listed there. I'm using SHA512, the password fields are long enough, etc.

app/config/security.yml

security:
    encoders:
        System\Bundle\DataBundle\Entity\SystemUser:
            algorithm: sha512

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]

    providers:
        administrators:
            entity: { class: SystemDataBundle:SystemUser }

    firewalls:
        dashboard:
            pattern:             ^/
            form_login:
                check_path:      /Dashboard/Login/Check
                login_path:      /Dashboard/Login
                use_forward:     false
                success_handler: system_user.security.authentication_handler
                failure_handler: system_user.security.authentication_handler
            anonymous: true
            logout:
                path:            /Dashboard/Logout
                target:          /
        admin_area:
            pattern:    ^/admin
            http_basic: ~

    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: /_wdt/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: /_profiler/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/Dashboard/(Login|LoginCheck|Logout)$, roles: IS_AUTHENTICATED_ANONYMOUSLY }

System/Bundle/Entity/SystemUserRepository.php

namespace System\Bundle\DataBundle\Entity;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;

class SystemUserRepository extends EntityRepository implements UserProviderInterface
{
    public function loadUserByUsername($emailAddress)
    {
        $q = $this
            ->createQueryBuilder('u')
            ->where('u.systemUserEmailAddress = :email')
            ->setParameter('email', $emailAddress)
            ->getQuery();

        try {
            // The Query::getSingleResult() method throws an exception
            // if there is no record matching the criteria.
            $SystemUser = $q->getSingleResult();
        } catch (NoResultException $e) {
            $message = sprintf(
                'Unable to find an active admin AcmeUserBundle:User object identified by "%s".',
                $emailAddress
            );
            throw new UsernameNotFoundException($message, 0, $e);
        }

        return $user;
    }

    public function refreshUser(UserInterface $systemUser)
    {
        $class = get_class($systemUser);
        if (!$this->supportsClass($class)) {
            throw new UnsupportedUserException(
                sprintf(
                    'Instances of "%s" are not supported.',
                    $class
                )
            );
        }

        return $this->find($systemUser->getSystemUserId());
    }

    public function supportsClass($class)
    {
        return $this->getEntityName() === $class
            || is_subclass_of($class, $this->getEntityName());
    }
}

System/Bundle/UserBundle/Security/AuthenticationHandler.php

namespace System\Bundle\UserBundle\Security;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;

class AuthenticationHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface
{
    private $router;
    private $session;

    public function __construct( RouterInterface $router, Session $session )
    {
        $this->router  = $router;
        $this->session = $session;
    }

    public function onAuthenticationSuccess( Request $request, TokenInterface $token )
    {
        // if AJAX login
        if ( $request->isXmlHttpRequest() ) {

            $array = array( 'success' => true ); // data to return via JSON
            $response = new Response( json_encode( $array ) );
            $response->headers->set( 'Content-Type', 'application/json' );

            return $response;

        // if form login 
        } else {

            if ( $this->session->get('_security.main.target_path' ) ) {

                $url = $this->session->get( '_security.main.target_path' );

            } else {

                $url = $this->router->generate( 'dashboard_home_homepage' );

            } // end if

            return new RedirectResponse( $url );

        }
    }

     public function onAuthenticationFailure( Request $request, AuthenticationException $exception )
    {
        // if AJAX login
        if ( $request->isXmlHttpRequest() ) {

            $array = array( 'success' => false, 'message' => $exception->getMessage() ); // data to return via JSON
            $response = new Response( json_encode( $array ) );
            $response->headers->set( 'Content-Type', 'application/json' );

            return $response;

        // if form login 
        } else {

            // set authentication exception to session
            $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);

            return new RedirectResponse( $this->router->generate( 'login_path' ) );
        }
    }
}

System/Bundle/UserBundle/Controller/SystemUserController/registerAction (bits and pieces)

    ...
    $tempSalt = uniqid(mt_rand());
    ...
    $SystemUser
        ...
        ->setSalt($tempSalt)
        ->setPassword(hash('sha512', $tempSalt . $parameters['password']))
        ...

I think these are all the relevant files. I'll happily add anything else that might be relevant. I think I'm confusing one of the references, but have torn my hair out enough. There are a few pieces of messy stuff (early development obviously) but nothing that interferes with the fundamental operation here (I hope!). Not all of my routes are finished, but I'd be more than happy to be redirected to the wrong place...

I'm a little over-normalized for the typical web project:

SystemUser
    PK SystemUserID
    FK SystemUserEmailAddressID
    FK SystemUserPhoneNumberID
    ...

I have no problem hydrating or dealing with these objects however, and the relationships seem to be correct based on the security.DEBUG logs above.

If there is a better method of salt/hash I will take that advice as well.

Thanks!

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
    • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
    • ¥20 有关区间dp的问题求解
    • ¥15 多电路系统共用电源的串扰问题
    • ¥15 slam rangenet++配置
    • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
    • ¥15 ubuntu子系统密码忘记
    • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
    • ¥15 保护模式-系统加载-段寄存器
    • ¥15 电脑桌面设定一个区域禁止鼠标操作