【问题标题】:Symfony2 authenticate users with api key access control issueSymfony2 使用 api 密钥访问控制问题对用户进行身份验证
【发布时间】:2015-12-07 12:38:02
【问题描述】:

您好,我正在为自己开发一个项目。我想要做的是验证除用户注册之外的所有对 api 的调用。我创建了用户身份验证和用户提供程序,如此链接中所述: http://symfony.com/doc/current/cookbook/security/api_key_authentication.html

一切正常,我后端的所有 url 都经过身份验证,并且由 UserTokenAuthenticator 和 UserTokenProvider 处理。但是它验证了everycall。我不想验证这个网址

    /v1.0/users with POST method

所以我在 security.yml 文件中设置了我的访问控制如下:

access_control:
    user_register:
        path: ^/v1.0/users
        roles: IS_AUTHENTICATED_ANONYMOUSLY
        methods: [POST]

但是,每当我尝试对此 url 进行 post 调用时,它都会尝试进行身份验证(因为调用没有令牌作为参数)并且它失败了。我怎样才能防止仅对该路由进行身份验证?这是我的完整代码:

security.yml:

security:
    encoders:
        entity_user:
            class: KBell\AppBundle\Entity\User
            algorithm: sha1
            iterations: 1
            encode_as_base64: false
        entity_device:
            class: KBell\AppBundle\Entity\Device
            algorithm: sha1
            iterations: 1
            encode_as_base64: false

    role_hierarchy:
        ROLE_DEVICE: ROLE_DEVICE
        ROLE_USER : ROLE_USER

    providers:
        entity_device:
            entity:
                class: KBell\AppBundle\Entity\Device
                property: name
        entity_user:
            entity:
                class: KBell\AppBundle\Entity\User
                property: email
        user_token_provider:
            id: user_token_provider
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        api_user_secured_area:
            pattern: ^/v1.0/users
            stateless: true
            simple_preauth:
                authenticator: user_token_authenticator
            provider: user_token_provider
    access_control:
        user_register:
            path: ^/v1.0/users
            roles: IS_AUTHENTICATED_ANONYMOUSLY
            methods: [POST]

这里是 UserTokenAuthenticator:

<?php

class UserTokenAuthenticator implements SimplePreAuthenticatorInterface,    AuthenticationFailureHandlerInterface
{

    public function createToken(Request $request, $providerKey)
    {
        $accessToken = $request->query->get('access_token');
        if (!$accessToken) {
            throw new BadCredentialsException('Access Token is missing');
        }

        return new PreAuthenticatedToken(
            'anon.',
            $accessToken,
            $providerKey
        );
    }

    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {
        $accessToken = $token->getCredentials();
        $user = $userProvider->getUserForAccessToken($accessToken);
        if (!$user) {
            throw new AuthenticationException(
                sprintf('Access Token "%s" does not exist.', $accessToken)
            );
        }

        return new PreAuthenticatedToken(
            $user,
            $accessToken,
            $providerKey,
            $user->getRoles()
        );
    }

    public function supportsToken(TokenInterface $token, $providerKey)
    {
        return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return ApiUtil::getJsonErrorResponse("User authentication is failed: ".$exception->getMessage(), Response::HTTP_UNAUTHORIZED, "AuthenticationException");
    }
}

这里是 UserTokenProvider.php:

class UserTokenProvider implements UserProviderInterface
{
    private $userManager;

    public function __construct(UserManager $userManager)
    {
        $this->userManager = $userManager;
    }

    public function getUserForAccessToken($accessToken)
    {
        $user = $this->userManager->findUserByAccessToken($accessToken);
        return $user;
    }

    public function loadUserByUsername($username)
    {
    }

    public function refreshUser(UserInterface $user)
    {
        throw new UnsupportedUserException();
    }

    public function supportsClass($class)
    {
        return 'Symfony\Component\Security\Core\User\User' === $class;
    }
}

我为此花了很多时间。任何帮助将不胜感激!谢谢!

【问题讨论】:

    标签: php api symfony authentication


    【解决方案1】:

    我认为您可以尝试像这样配置防火墙设置:

    firewalls:
        secured_user_area:
            pattern: /v(\d+\.?\d*)/(?!users)
            stateless: true
            provider: user_token_provider
    
        ....
    

    这里的?!users(甚至像?!users|URL2|URL3这样的多个网址)声明将网址排除在防火墙之外。

    【讨论】:

    • 它将允许所有其他方法(GET、PUT 等)到达/v1.0/users 端点。我只是希望 POST 不经过身份验证
    • 我也不知道为什么access_control不适用于这种情况?
    猜你喜欢
    • 1970-01-01
    • 2014-03-31
    • 2019-02-17
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 2019-08-25
    相关资源
    最近更新 更多