1

我想在执行身份验证之前执行用户名(字符数和有效电子邮件)和密码(字符数)的传统验证。

用户在数据库中,我不想在验证成功之前访问数据库。

我用 Symfony 4.1 设置了 LexikJWTAuthenticationBundle 并且它正在工作。没有控制器,因为身份验证完全由捆绑包处理。

我不确定如何执行上述验证。请帮忙。

在我的安全配置下方查找以了解我已经设置的内容。

security:
    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
    encoders:
        App\Entity\User:
            id: app.bcrypt_plus_encoder
    providers:
        db_user_provider:
            entity:
                class: App\Entity\User
                # the property to query by - e.g. username, email, etc
                property: email
                # if you're using multiple entity managers
                # manager_name: customer
    firewalls:
        guest:
            pattern: ^/api/guest
            stateless: true
            anonymous: true
        login:
            pattern:  ^/api/login
            user_checker: App\Security\UserChecker
            stateless: true
            anonymous: true
            provider: db_user_provider
            json_login:
                check_path: /api/login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: App\Security\Http\Authentication\AuthenticationFailureHandler
                require_previous_session: false
                username_path: email
                password_path: passw

        api:
            pattern:   ^/api
            stateless: true
            guard:
                provider: db_user_provider
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

    access_control:
        - { path: ^/api/guest, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }
4

1 回答 1

1

您好,如果您想处理请求用户名和密码,您可以添加 Guard Authenticator 并在 <<supports >> 函数中添加您的逻辑条件,如下所示:

<?php

namespace App\Security;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;

class UserAuthenticator extends AbstractGuardAuthenticator
{
    public function supports(Request $request)
    {
        // here you can handle your request an throw exception if not valid


        // throw new UsernameNotFoundException(
        //     sprintf('Username "%s" does not exist.', 'test')
        // );
        // dump($request->getContent());die;
        
        return $request->headers->has('X-AUTH-TOKEN');
    }

    public function getCredentials(Request $request)
    {
        return array(
            'token' => $request->headers->get('X-AUTH-TOKEN'),
        );
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $apiKey = $credentials['token'];

        if (null === $apiKey) {
            return;
        }
        return $userProvider->loadUserByUsername($apiKey);
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return true;
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        return null;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        $data = array(
            'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
        );

        return new JsonResponse($data, Response::HTTP_FORBIDDEN);
    }

    public function start(Request $request, AuthenticationException $authException = null)
    {
        $data = array(
            // you might translate this message
            'message' => 'Authentication Required'
        );

        return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
    }

    public function supportsRememberMe()
    {
        return false;
    }
}

只需在 security.yml 中添加您的 Guard,如下所示:

security:
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    encoders:
        App\Entity\User: bcrypt
    providers:
        jwt:
            lexik_jwt: ~
        user_provider:
            entity:
                class: App\Entity\User
                property: username

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern:  ^/api/login
            stateless: true
            anonymous: true
            provider: user_provider
            json_login:
                check_path:               /api/login_check
                success_handler:          lexik_jwt_authentication.handler.authentication_success
                failure_handler:          lexik_jwt_authentication.handler.authentication_failure
            guard:
                authenticators:
                    - App\Security\UserAuthenticator

于 2018-11-24T00:38:06.333 回答