Symfony使用外部api密钥对用户进行身份验证

时间:2014-02-27 22:51:04

标签: api symfony authentication

我正在尝试通过此http://symfony.com/doc/current/cookbook/security/api_key_authentication.html#cookbook-security-api-key-config

之后的外部API密钥请求对用户进行身份验证

什么是[“@your_api_key_user_provider”]? 如果我输入类似[“test”]的内容,我会收到错误。

[UPDATE]

这是我的ApiKeyAuthenticator.php:

// src/Acme/HelloBundle/Security/ApiKeyAuthenticator.php

 namespace Acme\HelloBundle\Security;
 use ////

 class ApiKeyAuthenticator implements SimplePreAuthenticatorInterface
 {
protected $userProvider;

public function __construct(ApiKeyUserProvider $userProvider)
{
    $this->userProvider = $userProvider;
}

public function createToken(Request $request, $providerKey)
{
    if (!$request->query->has('apikey')) {
        throw new BadCredentialsException('No API key found');
    }

    return new PreAuthenticatedToken(
        'anon.',
        $request->query->get('apikey'),
        $providerKey
    );
}

public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
    $apiKey = $token->getCredentials();
    $username = $this->userProvider->getUsernameForApiKey($apiKey);

    if (!$username) {
        throw new AuthenticationException(
            sprintf('API Key "%s" does not exist.', $apiKey)
        );
    }

    $user = $this->userProvider->loadUserByUsername($username);

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

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

}

虽然用户提供商是这样的:

// src/Acme/HelloBundle/Security/ApiKeyUserProvider.php

命名空间Acme \ HelloBundle \ Security;

use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;

  class ApiKeyUserProvider implements UserProviderInterface
 {
public function getUsernameForApiKey($apiKey)
{
    // Look up the username based on the token in the database, via
    // an API call, or do something entirely different
    $username = ...;

    return $username;
}

public function loadUserByUsername($username)
{
    return new User(
        $username,
        null,
        // the roles for the user - you may choose to determine
        // these dynamically somehow based on the user
        array('ROLE_USER')
    );
}

public function refreshUser(UserInterface $user)
{
    // this is used for storing authentication in the session
    // but in this example, the token is sent in each request,
    // so authentication can be stateless. Throwing this exception
    // is proper to make things stateless
    throw new UnsupportedUserException();
}

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

服务应该就是这样:

services:
# ...

apikey_authenticator:
    class:     Acme\SeedBundle\Security\ApiKeyAuthenticator
    arguments: ["@ApiKeyUserProvider"]

但我得到了这个错误:服务“apikey_authenticator”依赖于不存在的服务“apikeyuserprovider”。

由于

1 个答案:

答案 0 :(得分:4)

这是您应该按照以下文档创建的用户提供程序服务:

http://symfony.com/doc/current/cookbook/security/custom_provider.html

因此,您将用户提供商注册为服务IE:apikey_userprovider http://symfony.com/doc/current/cookbook/security/custom_provider.html#create-a-service-for-the-user-provider

然后使用["@apikey_userprovider"]

传递它

因此,您的服务文件应如下所示:

parameters:
    apikey_userprovider.class: Acme\HelloBundle\Security\ApiKeyUserProvider
    apikey_authenticator.class: Acme\SeedBundle\Security\ApiKeyAuthenticator
services:
    apikey_userprovider:
        class: %apikey_userprovider.class%
    apikey_authenticator:
      class: %apikey_authenticator.class%
      arguments: ["@apikey_userprovider"]

您需要将用户提供程序定义为服务。这就是@运算符告诉symfony寻找的东西。在参数中定义类只是Symfony Coding Standards

的一部分