Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony-guard:访问控制无效_Php_Symfony - Fatal编程技术网

Php Symfony-guard:访问控制无效

Php Symfony-guard:访问控制无效,php,symfony,Php,Symfony,我是symfony的新手,我正在尝试获得一个基于JWT的基本guard验证器。这项工作主要来自本文,我已经删除了任何用户检查(目前): 我想有些东西我不明白,因为我不能让它工作。更准确地说,它在任何地方都能起作用,甚至在我提出的例外情况下也是如此 以下是检查服务,与本文基本相同,没有用户管理,并且有一些日志记录: <?php namespace AppBundle\Security; use Lexik\Bundle\JWTAuthenticationBundle\Encoder\De

我是symfony的新手,我正在尝试获得一个基于JWT的基本guard验证器。这项工作主要来自本文,我已经删除了任何用户检查(目前):

我想有些东西我不明白,因为我不能让它工作。更准确地说,它在任何地方都能起作用,甚至在我提出的例外情况下也是如此

以下是检查服务,与本文基本相同,没有用户管理,并且有一些日志记录:

<?php

namespace AppBundle\Security;

use Lexik\Bundle\JWTAuthenticationBundle\Encoder\DefaultEncoder;
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\AuthorizationHeaderTokenExtractor;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Psr\Log\LoggerInterface;

class TokenAuthenticator extends AbstractGuardAuthenticator
{
    private $jwtEncoder;
    private $logger;

    public function __construct(DefaultEncoder $jwtEncoder, LoggerInterface $logger)
    {
        $this->logger = $logger;
        $this->jwtEncoder = $jwtEncoder;
    }

    public function start(Request $request, AuthenticationException $authException = null)
    {
        $route = $request->attributes->get('_route');
        $url = $request->getUri();
        $this->logger->info($route . ' : ' . $url);
        return new JsonResponse('Authentication required', 401);
    }

    public function getCredentials(Request $request)
    {

        if(!$request->headers->has('Authorization')) {
            return;
        }

        $extractor = new AuthorizationHeaderTokenExtractor(
            'Bearer',
            'Authorization'
        );

        $token = $extractor->extract($request);

        if(!$token) {
            return;
        }

        return $token;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $data = $this->jwtEncoder->decode($credentials);

        if(!$data){
            return;
        }

        $username = $data['username'];

        // TODO get user from user collection
        $user = ['username' => $username];

        // Is user is encoded in token and exists, then it's fine
        if(!$user){
            return;
        }

        return $user;
    }


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

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return new JsonResponse([
            'message' => $exception->getMessage()
        ], 401);
    }

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

    public function supportsRememberMe()
    {
        return false;
    }

}
我只是在^/api上设置了保护,并在同一路径上设置了一个控件访问,以允许匿名。我希望在该配置的任何路径上都不会调用guard服务,但每次都会调用它。我想我对它的工作原理缺乏了解。 我的理解是:

  • 在进行任何其他操作之前检查访问控制
  • 如果有一条匹配的线,它会接受它(第一条)
  • 如果设置了匿名身份验证,则不检查防火墙
  • 否则,下一个检查是防火墙配置,它告诉您使用令牌身份验证器进行检查
最初的目标是锁定/api,除了可以不受控制地访问的/api/auth和/api/version之外


谢谢你的帮助,我想在这件事上一天半之后,我无法直接思考它。

为了记录在案,我设法解决了这个问题

首先,Guard Authenticator构建在真实的用户存储库上,这不是我们想要的。我们希望快速检查Redis,并在Mongo中创建用户存储库。此外,我们不需要PHP会话,我们需要一个无状态系统(只有活动令牌在redis中)

所以我所做的就是为Guard Authenticator创建一个虚拟用户对象,实现所需的接口

在访问时,我们通过在redis中获取其令牌以及其他数据来检查用户是否已经知道。这些附加数据包括所需的用户对象

在连接时,我们实际上检查数据库中的用户,如果没有问题,我们创建虚拟用户对象,并使用令牌将其推送到redis中


有了这个系统,一切都很好。这不是最漂亮的解决方案,但它允许在可能有多个实例的无状态环境中使用Guard。

您好,我最近遇到了同样的问题。当我们有带有acces\U控件的自定义guard authenticator时,缺乏关于这个用例的良好文档

首先:

我的理解是:

  • 在进行任何其他操作之前检查访问控制
不,这句话是失败的,正因为如此,它表达了对其余部分的理解

例如,您可以看到,防火墙(您的令牌身份验证程序守护程序)的任务是启动身份验证过程,这是系统所做的第一件事-检查给定的凭据(如果有)是否会产生经过身份验证的令牌

如果确定了这一点,则系统将执行其第二个作业,即授权——例如,由于使用访问控制的角色不足,可能会拒绝对某些资源的访问

了解了所有这些,您可以将guard token authenticator视为某种(我知道它不是真实的东西,只是为了清楚地解释)登录表单机制的抽象虚拟变体,它只会在您点击登录路径时运行。唯一的区别是,当请求具有授权头时,而不是当您点击某个登录路径时,您的防护将运行(这是完全可自定义的,就像您在getCredentials函数中定义的那样)

顺便说一句,在最新的symfony中,在getCredentials之前调用,您应该在其中检查请求是否有足够的头来启动身份验证(或任何您想要的检查)

所以基本上你们说:“当请求有授权头时运行guard”,不管你们请求哪个uri。可能是因为您以这种方式发送基本的身份验证凭据—您的请求(甚至对于api/version,尤其是对于api/auth)具有此标头。然后你的守卫会在任何导致你描述的行为之前被触发

作为一种可能的解决方案-在您的保护内部,您可以将其设置为在请求具有X-AUTH-TOKEN头时触发(因此您可以对公共访问路径使用不同的头,对私有访问路径使用不同的头)。这样,您对api/version的调用不会触发guard,甚至对api/auth的调用也不会触发guard,因为您将使用授权头而不是X-auth-TOKEN头发送凭据

如果是这样,您的防护将不会被触发,然后使用已确定的未经身份验证的令牌,您点击您的访问控制,该控制将决定是否允许您使用资源(对于该路径,是匿名认证的)


我希望我能给你解释一下。

谢谢你的解释,但是这个问题并不是真的发生在auth或其他方面。只是从一开始就没有考虑过这个用例。像我一样实现存储库,最终让我们可以做我们想要做的事情,我想这是在这种情况下我们能做的最好的事情。我希望Symfony会重新考虑它的保护系统,以适应新的范例,但就我而言,我不再使用它了:)
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:

    # http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
    providers:
        in_memory:
            memory: ~

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

#################################
# Secured section
#

        # Custom authentication firewall for all request thats starts from /api
        api:
            pattern: ^/api
            guard:
                authenticators:
                    - app.token_authenticator


#################################
# Main Configuration
#

        main:
            anonymous: ~
            # activate different ways to authenticate

            # http_basic: ~
            # http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate

            # form_login: ~
            # http://symfony.com/doc/current/cookbook/security/form_login_setup.html



    access_control:
        #- { path: ^/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        #- { path: ^/version, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        #- { path: ^/api, roles: [ROLE_USER, ROLE_API_USER] }
        - { path: ^/api, roles: IS_AUTHENTICATED_ANONYMOUSLY }

        #- { path: ^/(css|js), roles: IS_AUTHENTICATED_ANONYMOUSLY }
        #- { path: ^/(_wdt|_profiler), roles: IS_AUTHENTICATED_ANONYMOUSLY }
        #- { path: ^/, roles: ROLE_USER }